Getting Started With AngularJS – Controller

In this blog post we will see more about angular controllers

Controllers are angular function which are used to bind data and $scope, inject services and setup initial state.

Controller Scope and Functions

We have already seen before how to pass data through controller scope to HTML and bind it using ng-model.
We can similarly also add functions to scope, let’s see how.

<body ng-app='MainApp'>
    <div ng-controller='MainCtrl'>
      <div>
        <input type='button' value='Hello' ng-click='hello();' />
        <input type='button' value='Hi' ng-click='hi();' />
      </div>
      <div>
        <p>Text: {{text}}</p>
      </div>
    </div>
</body>
var mainMod = angular.module('MainApp', []);

mainMod.controller('MainCtrl', function ($scope) {
    $scope.text = '!!';
     
    $scope.hello = function(){
         $scope.text = 'Hello';
    }
    $scope.hi  = function(){
      $scope.text = 'Hi';
    }
});

In above code, i have created two function hello and hi, and called it using the ng-click directive. Now i will this another step further and pass arguments to the functions

var mainMod = angular.module('MainApp', []);

mainMod.controller('MainCtrl', function ($scope) {
    $scope.text = '!!';
     
    $scope.hello = function(text){
         $scope.text = text + 'Hello';
    }
    $scope.hi  = function(text){
      $scope.text = text + 'Hi';
    }
});
<body ng-app='MainApp'>
    <div ng-controller='MainCtrl'>
      <div>
        <input type='button' value='Hello' ng-click='hello(text);' />
        <input type='button' value='Hi' ng-click='hi(text);' />
      </div>
      <div>
        <p>Text: {{text}}</p>
      </div>
    </div>
</body>


As we can see above, we able to pass $scope variable as argument to functions. This is a powerful feature in angular and is quite useful in many cases.

More details on controllers can be seen here https://docs.angularjs.org/guide/controller

Controller Dependency Injection

Till now, when ever we have defined a controller we use $scope as the argument to the controller.

mainMod.controller('MainCtrl', function ($scope){});

We will see now how exactly the $scope is passed to the controller by angular.
$scope is essentially a ‘service’ in angularjs. Service’s are basically object, which are shared across modules and usually contain logic which is shared across modules. Angular provides many inbuilt service like $http, $rootScope, $scope, $q, $location, $window etc, and we can also create custom services.

So angular passes service objects to controllers using dependency injection. It is important to note here that, angular matches service object using the name of variables which are passed to the function.
e.g ‘$scope’ passed as function argument match the $scope service. If we change the variable name to say $scopes, angular will be able to match service object hence not able to inject it.

Similarly we can inject more services to controller simply by adding arguments

mainMod.controller('MainCtrl', function ($scope,$rootScope,$http){});

Since, the variable name is important for angular to resolve dependency of service, we cannot minify the javascript files. Minification replaces variable name with shorter variables, which will break angular DI. To fix this, its always best to define a controller like this

mainMod.controller('MainCtrl', ['$scope','$rootScope','$http',function ($scope,$rootScope,$http){

}]);

In the above case, angular resolves service objects with name service names passed in arrary. So even minification won’t cause a problem.