0

I have recently seen situations like this:

app.controller('MainCtrl', ['$scope', 'MyService', function($scope, MyService) { 
    $scope.name = 'World';
    var self = this;

    $scope.operationOne = function() {         
        MyService.sayHello(); 
        self.someCommonBehaviour(); 
    }

    $scope.operationTwo = function() {     
        MyService.sayGoodbye(); 
        self.someCommonBehaviour(); 
    }

    this.someCommonBehaviour = function() {
    }
}]);

There is some common functionality between functions attached to the scope that is extracted to a function. As we need a reference to the controller to access 'someCommonBehaviour' we append the function to 'this' and store a reference of this in self, so we can access it in the $scope functions (this in the scope is the scope in effect when the function was called).

Functions as 'someCommonBehaviour' can be accessed from the outside (ctrl.someCommonBehaviour()). I think that, at least in the cases that I have seen, the intent is clearly leave those functions as a private concern of the controller. The fact that they can be accessed is an accident.

Moreover, I have seen situations where the programmer is trying to add more logic into an already complicated controller and they fall into the temptation of testing those functions, something that you should not do.

I'm looking for a way of preventing those functions from being accessed from the outside.

I was thinking about IIFE, as they allow you to control the functions that will define the public API of your module (and that is the implementation that I choose for services). It feels weird that the only API that I want for this case is defined by the functions that I add to the scope. So, you would have something like:

(function(module) {
    var controller = function($scope, MyService) {
        $scope.methodOne = function(
        ...
        ...
        return { }
    };
    module.controller('controller', ['$scope','MyService',controller]);
})(angular.module('app');

I think it should work, but it feels so strange returning an empty object.

Am I missing something?. What is the best approach?.

1 Answer 1

6

Just don't attach it to this. Only the code inside the controller will ever see it.

app.controller('MainCtrl', ['$scope', 'MyService', function($scope, MyService) { 
    $scope.name = 'World';
    var self = this;

    $scope.operationOne = function() {         
        MyService.sayHello(); 
        someCommonBehaviour(); 
    }

    $scope.operationTwo = function() {     
        MyService.sayGoodbye(); 
        someCommonBehaviour(); 
    }

    // Not accessible outside controller
    function someCommonBehaviour() {

    }
}]);
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. So obvious when you have the answer :-).

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.