5

I am using ES6 class to define my controller so this is the syntax,

export class SearchBarController {
    constructor($log) {
        'ngInject';

        $log.debug("Hello");
    }

    textTyped($log){

        $log.debug("change fired.");
    }
} 

view :

<input type="text" data-ng-model="vm.txt" data-ng-change="vm.textTyped()"/>

So "Hello" from within the constructor is getting logged fine. But, "change fired" within the typedText() function is not firing because apparently is undefined how do I make my class function textTyped() to access the $log service?

Note : If I assign $log to a class property in the constructor like,

this.logger = $log;

And then do,

this.logger.debug("Change fired.");

this works. But I am unsure if it's the right approach.

Update: Also, this approach exposes this reference to the $log service to the view bound to this controller. Is this harmful?

Is there a better solution?

2
  • 1
    this.logger = $log is the recommended approach. Commented Mar 27, 2016 at 21:10
  • ok thanks. But wouldn't adding it to 'this' expose it directly to the viewModel/$scope? Commented Mar 27, 2016 at 21:18

3 Answers 3

2
this.logger = $log;

As you pointed out, is the way. Since it's an object, there is no global scope.

Sign up to request clarification or add additional context in comments.

1 Comment

But wouldn't adding it to 'this' expose it directly to the viewModel/$scope?
2
class SearchBarController {
    constructor($scope, $log) {
        this.log = $log;

        // Scope method
        $scope.vm = this;
    }

    textTyped(){
        this.log.debug("change fired.");
    }
}

SearchBarController.$inject = ['$scope', '$log'];

Try like this

1 Comment

this approach exposes this reference to the $log service to the view bound to this controller. Is this harmful? I can simply in the view do {{ controllerAs.log.debug("Abc") }}. It's ok with log but what if some other more critical service get's exposed like this?
2

In case anyone's interested I found a more elegant solution to the problem using ES6 Object Destructuring :

class ABCController {
    constructor($log, $http){
        let vm = this;
        vm.DI = () => ({$log, $http});
    }

    classFn(){
        let vm = this;
        let {$log, $http} = vm.DI();
        //Now use $log and $http straightway

        $log.debug("Testing");
        $http({...}).then();
    }

    classFn2(){
        let vm = this;
        //you can also destructure only the required dependencies in this way
        let {$http} = vm.DI();
    }
}
ABCController.$inject = ['$log', '$http'];

In this way you don't need to write ugly/confusing code like vm.DI.log, etc. Also, in this way the DIs are less exposed in the view.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.