angularjsvisual-studio-2015angularjs-controllerangularjs-injectorself-invoking-function

Visual Studio's AngularJS Template Explained


When I create a new controller using VS2015 templates I get this code:

(function () {
    'use strict';

    angular
        .module('app')
        .controller('controller', controller);

    controller.$inject = ['$scope']; 

    function controller($scope) {
        $scope.title = 'controller';

        activate();

        function activate() { }
    }
})();

Questions:

  1. Why does VS template wraps the code in a self invocing function?

  2. What's the thing with the activate() function? What code do I suppose to write inside and why do I need a seperate function instead of just writing the code inside the controller?

  3. Do the controller.$inject = ['$scope']; considered a better practice then writing the dependencies in an array (as an argument of the controller function).


Solution

  • Why does VS template wraps the code in a self invoking function?

    Because it prevents corrupting global namespace. In this case, controller will become a member of global namespace in the absence of IIFE.

    What's the thing with the activate() function?

    It helps separating declaration and execution of controller variables and code respectively. Prior to calling the activate function, we usually declare all the dependencies as the controller members using this. syntax.

    You will write the executing code inside the activate function.

    Do the controller.$inject = ['$scope']; considered a better practice?

    Actually yes! It helps you to separate your controller definition from it's angular counterpart. It helps you to avoid writing the entire controller code in angular.module( ... ).controller block to improve readability of your code.

    Edit 1:

    Without the IIFE, the function named controller will become a member of the global namespace, and will be accessible throughout your page. It will also pose a possiblity of being overwritten by subsequent code. Don't mix AngularJS with this, because this is something which JavaScript does.

    The activate function is just a layer to separate the concerns. You can write your code entirely in the function controller. But in that way, it becomes harder to separate which code controller is executing, and which code binds the variables to controller. Take this example:

    function controller($scope) {
      var vm = this;
      vm.data = [];
      $scope.title = 'controller';
    
      activate();
    
      ///
      function activate() {
        getData()
          .then(data => {
            // do something with data
          });
    
        // ...
      }
    
      function getData() {
        ...
      }
    }
    

    By reading the above code, one can easily know about the variables being used down the line in the controller, without specifically going into the depth of the controller. By following this convention, we will always know that the controller will start executing the business logic right where activate() is called.