AngularJS Controllers Explained with Examples

AngularJS Controllers are most useful part of an AngularJS application. These are javascript functions/objects which perform majority of UI related work. They can be considered as the driver for Model and View changes. They are the gateway between the model (the data in our application), and the view (whatever a users sees on his screen and interacts with).

Their core responsibilities includes:

  • Providing Data to UI. Data can be static or fetched from server.
  • Managing presentation logic, such as which element to show/hide, what style to apply on them, etc.
  • Handling user input, such as what happens when a user clicks something or how a text input should be validated
  • Processing data from user input to be sent to server

Basic Syntax

angular.module('myApp', [])
.controller('AppController', [function() {
    var self= this;
    self.name = 'BLA BLA';
}]);

or if the module is defined elsewhere.

var App = angular.module('myApp',['ui.bootstrap', 'ngResource']);//in some file

App.controller('AppController', [function() {
    var self= this;
    self.name = 'BLA BLA';
}]);
  • Controllers are created as part of a module. Use angular.module function to create a module if it does not exist
  • Once you have a module, you can create a controller using the controller function on the module.
  • controller function takes two arguments. First is the name of Controller [‘AppController’ in this example], and second argument is controller definition function which contains the actual logic of controller.
  • Take special notice of how we have defined our controller definition function inside an array. The array holds all the dependencies for the controller as string variables, and the last argument in the array is the actual controller function. In this case, because we have no dependencies, the function is the only argument in the array.

Controller with Dependencies

var App = angular.module('myApp',['ui.bootstrap', 'ngResource']);//in some file

App.controller('AppController', ['$log', '$location', function($log, $location) {
    var self= this;
    self.name = 'BLA BLA';
    self.sayHello = function(){alert('say hello');}
    $log.log('I am starting');
    $location.path("/newpath")
}]);

In above example, our controller depends on few built-in AngularJS services [$log service used to simply log strings to console, $location service used to interact with the URL in the browser bar]. First we need to add the dependencies as strings in the array (this is known as ‘safe style of Dependency Injection’). Then we will inject them as variables (you can give it any name) into the function that is passed as the last argument in the array.

AngularJS will pick up the individual strings in the array, look up the services internally, and inject them into the function in the order in which we have defined the strings. Once the services are injected, we can use them within our controller. In this case, the controller definition function simply logs a string to the console, and set the URL to /newpath.

How to use a controller in UI ?

Using ng-controller directive.

  <body ng-controller="AppController as ctrl">
  
    <label>Name :</label><input type="text" ng-model="ctrl.name" placeholder="Enter your name"/><br/><br/>  

    <span ng-bind="ctrl.name"></span><br/><br/>  

    <button ng-click="ctrl.sayHello()"> Hello </button>
   .....
   </body>

In order to use a Controller in UI, we make use of another popular AngularJS directive : ng-controller. This directive is primarily used to associate an instance of a controller with a UI element. In this particular example, we applied it on body.

controllerAs syntax

With ng-controller, we have provided a name to this particular instance of AppController, called ctrl using as keyword. This is known as the controllerAs syntax in AngularJS [Bla as b]. Using controllerAs syntax, we can give each instance of the controller a name in order to recognize its usage in the HTML. Note that we can even have different instances of same controller used in different places in UI, in that case controllerAs will be handy to relate which instance is controlling which part of HTML.

I can’t see $scope in my controller ???

Anyone coming from AngualrJS background will be wondering where all those $scope stuff have gone. With the new controllerAs syntax, you can simply avoid using $scope unless in specific situations. The controllerAs syntax gives a clear impression when looking in HTML about who is doing what in UI.

Just for comparison, let’s rewrite above snippet using $scope this time:

var App = angular.module('myApp',['ui.bootstrap', 'ngResource']);//in some file
 
App.controller('AppController', ['$scope','$log', '$location', function($scope, $log, $location) {
    $scope.name = 'BLA BLA';
    $scope.sayHello = function(){alert('say hello');}
    $log.log('I am starting');
    $location.path("/newpath")

}]);

This time, instead of using this, we are creating a property and a function directly on $scope which we have added as a dependency, and will be injected by AngularJS. Now let’s see what our view will look like:

  <body ng-controller="AppController">
  
    <label>Name :</label><input type="text" ng-model="name" placeholder="Enter your name"/><br/><br/>  

    <span ng-bind="name"></span><br/><br/>  

    <button ng-click="sayHello()"> Hello </button>

   .....
   </body>

In above snippet, we have removed the controllerAs syntax, just controller name. As a result we are directly using the property and function by their names. This may seem nice here, but imagine when you have a complicated UI involving different components, it will make it hard for anyone reading the code to understand which property or function belongs to which component. This is one of reason to prefer controllerAs syntax over $scope counterpart.


A quick summary on scope:

One of the best explanation available on AngualrJS scope can be found at This link, which will answer all your scope related questions. In this section, however, i will just put few words from 30000 feet view.

  • Every Angular application has a single root scope that can be accessed using $rootScope. Application may have several other scopes [child scopes]. All other scopes are descendant scopes of the root scope. AngularJS scope follows JavaScript Prototypal Inheritance in that child scope inherit from parent scope.
  • A Scope in general is an object that refers to the application model. It acts as a context for an element in your HTML DOM. Each & every element in your HTML lives under a scope, whether it is it’s own scope or a parent scope. If the element has not defined it’s own scope, it is using scope from it’s parent.
  • Scopes are arranged in hierarchical structure which mimic the DOM structure of the application. Some AngularJS elements [like ng-Controller/ng-repeat/ng-switch/directives with scope:true e.g.] create there own child scope.
  • You may also treat the scope as a bridge between model & view. For instance, AngularJS components [controllers e.g.] can create properties and methods on scope, write data on those properties, which can then be accessed in view [HTML] by them (& optionally by their children).
  • Scopes are attached to the DOM as $scope data property. If declared as a dependency, AngularJS injects $scope in your component javascript.
  • Scopes provide APIs ($watch) to observe model changes.
  • Scopes provide APIs ($apply) to propagate any model changes through the system into the view from outside of the “Angular realm” (controllers, services, Angular event handlers).
  • Scopes can propagate events in similar fashion to DOM events. The event can be broadcasted to the scope children or emitted to scope parents.

Complete Example

Look at this example.

<html ng-app="myApp">
  <head>  
    <title>Controller Demo</title>  
  </head>
  <body ng-controller="AppController as ctrl">
  
    <label>Name :</label><input type="text" ng-model="ctrl.name" placeholder="Enter your name"/><br/><br/>  

    <span ng-bind="ctrl.message"></span> <span ng-bind="ctrl.name"></span><br/><br/>  

    <button ng-click="ctrl.changeMessage()"> Change Message </button>  
    <button ng-click="ctrl.resetMessage()"> Reset Message </button>  

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js">
    </script>  
    <script>
      angular.module('myApp', [])
      .controller('AppController', [function() {
          var self = this;
          self.name='';
          self.message= 'Hello';
          self.changeMessage = function() {
              self.message = 'Bye';
          };
          self.resetMessage = function() {
              self.message = 'Hello';
          };
      }]);
  </script>
  </body>
</html>

Live Demo

Let’s dig deeper into details.

  • We started by defining a module named ‘myApp’ which will be used to bootstrap this application.
  • We defined a controller named AppController using the controller function on the module.
  • We defined two variables name and message on the controller’s instance (using the this keyword).
  • To use this controller in the UI , we make use of another popular directive ng-controller. This directive is primarily used to associate an instance of a controller with a UI element. In this particular example, we applied it on body.
  • With ng-controller, we have provided a name to this particular instance of AppController, called ctrl. This is known as the controllerAs syntax in AngularJS. Using controllerAs syntax, we can give each instance of the controller a name in order to recognize its usage in the HTML. Note that we can even have different instances of same controller used in different places in UI, in that case controllerAs will be handy to relate which instance is controlling which part of HTML
  • On input tag, we used ng-model directive to store the value that the user types into this field into Controller’s ‘name’ variable.
  • We then bind the name and message variables from the controller in the HTML using ng-bind.
  • We also have two buttons on UI with the label “Change Message” & “Reset Message”. We have placed a built-in directive on them, ng-click. The ng-click directive evaluates any expression passed to it when the button is clicked. In this case, we ask AngularJS to trigger the controller’s changeMessage()/resetMessage() functions when clicked.
  • The changeMessage() function in the controller simply sets the value of message to “Bye.”, while resetMessage() function sets the value of message back to “Hello.”

When you type something in text box, the view is updated immediately to reflect it, thanks to AngularJS data-binding. Additionally, on startup, Application shows ‘Hello’ message but on clicking the changeMessage button (which simply sets the message variable in controller to a different value), the text in UI changes to ‘Bye’. It is interesting because we did not have to tell the UI to update. It happened automatically.


Nested Controllers Example

In a complex design, We can well face a need of nested controllers. AngularJS controllerAs again help us there to identify the individual instances/parent instances.

Look at below example.

<html ng-app="myApp">
    <head>  
        <title>Nested Controller Demo</title>  
        <style>
          body{font-family:"Arial";background-color:#E2E2DC}
          div {
            margin:10px;padding:10px;
            border:2px solid red;
          } 
        </style>  
    </head>
    <body>
        <div ng-controller="FirstController as first">
            type : {{ first.type }}
            <div ng-controller="SecondController as second">
                type: {{ second.type }}
                Parent type: {{ first.type }}
                <div ng-controller="ThirdController as third">
                    type: {{ third.type }}
                    Parent type: {{ second.type }}
                    Parent parent type: {{ first.type }}
                </div>
            </div>
        </div>
   
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js">
        </script>  
        <script>
            angular.module('myApp', [])
            .controller('FirstController', [function() {
                var self = this;
                self.type='FirstController';
            }])
            .controller('SecondController', [function() {
                var self = this;
                self.type='SecondController';
            }])
            .controller('ThirdController', [function() {
                var self = this;
                self.type='ThirdController';
            }]);
        </script>
    </body>
</html>

Live Demo

An AngularJS controller is directly linked to a view or HTML. If your controller contains some logic which is not used in UI, then it should not be there in controller at first place, and you should move that logic to Services.