Creating an AngularJS Controller

Wednesday 10 April 2013



  1. Getting started with AngularJS
  2. Creating an AngularJS Controller
  3. The AngularJS $scope is not the MVC Model
  4. Using repeating elements in AngularJS
  5. Filtering the data in an AngularJS ngRepeat element
  6. Using the AngularJS FormController to control form submission
  7. Creating an AngularJS Directive


In the previous blog post I showed how to get started with a really minimal AngularJS application. Even though the app could multiply two numbers it could hardly be called useful and as it turns out that is about as much as I could do with it.


Model View Controller

AngularJS is an MVC framework. So far we have only seen the View part as the HTML used was the view used to render the page to the user. As the name suggest there should be more in the form of a Controller and a Model.

The Controller part of an MVC application is normally the glue that ties a specific part of that application together. It gathers the data (Model) together and tells the View to render the data to the user. It also responds to events to do things.

Suppose we want to expand on the simple page from the previous post and turn this into a simple calculator, like in the screenshot below, the controller would be responsible for the calculations and the view would just be about displaying the data and not, like with the previous example, contain the actual calculation.



The AngularJS Controller

The controller that drives the logic of the application is a pretty simple JavaScript constructor function. As this is used with the new keyword to create an object I have capitalized the first letter as is the convention in JavaScript.


   1: function DemoCtrl($scope) {
   2:     $scope.x = 2;
   3:     $scope.y = 3;
   4:     $scope.result = "?";
   5:     $scope.operator = "?";
   7:     $scope.multiply = function() {
   8:         $scope.operator = "*";
   9:         $scope.result = (+$scope.x) * (+$scope.y);
  10:     };
  12:     $scope.add = function () {
  13:         $scope.operator = "+";
  14:         $scope.result = (+$scope.x) + (+$scope.y);
  15:     };
  16: }


The code basically consists of the X and Y value to be used in the calculation, two functions for adding and multiplying and a way to show the result and operator used. Adding two more functions for divide and subtract should be a simple enough exercise. The code is simple enough and pretty standard JavaScript. For those not used to JavaScript the (+$scope.x) expression is one of the ways you can convert a string to a number in JavaScript.

One special AngularJS thing is the $scope variable passed into the function and used.


What is the $scope?

The $scope variable is inserted automatically by AngularJS and serves as the bridge to share data between the controller and the view. Each variable added to the $scope is automatically be available for use in view data binding expressions. In fact there is always a scope, in the example from the previous the values where still stored in an AngularJS scope even though no controller was used.

The way AngularJS knows what to pass to the controller function is determined by the name. Just because we named it $scope AngularJS knows what to pass. This is done by a mechanism called dependency injection which is a very powerful mechanism used to separate different parts of the application and wire them up automatically at runtime while allowing us to pass in dummy services for testing purposes.


The AngularJS View

The view used is similar to the example from the previous blog post.


   1: <!DOCTYPE html>
   2: <html lang="en">
   3: <head>
   4:     <title>AngularJS Demo</title>
   5:     <meta http-equiv="content-type" content="text/html;charset=UTF-8" />
   6: </head>
   7:     <body ng-app ng-controller="DemoCtrl">
   8:         <input type="text" ng-model="x"/>
   9:         {{operator}}
  10:         <input type="text" ng-model="y"/>
  12:         <button ng-click="add()">+</button>
  13:         <button ng-click="multiply()">*</button>
  15:         = {{result}}
  17:         <script src="Scripts/angular.js"></script>
   2:         <script src="App/Controllers/DemoCtrl.js">
  18:     </body>
  19: </html>


New is the ng-controller attribute that tells AngularJS to create the controller and what part of the HTML view it controls. In the view we don’t have to use the $scope variable, every expression is always evaluated scoped to the current $scope.


Testing the controller

One of the reasons for using an MVC framework is the capability to test the code. As the controller has no requirements for testing it should be easy enough to test it. Below is a test for adding two numbers using QUnit.


   1: test("Test adding 3 + 7", function () {
   2:     // Arrange
   3:     var scope = {};
   4:     var ctrl = new DemoCtrl(scope);
   5:     scope.x = "3";
   6:     scope.y = "7";
   8:     // Act
   9:     scope.add();
  11:     // Assert
  12:     ok(scope.operator === "+", "The operator should be +");
  13:     ok(scope.result === 10, "3 + 7 should be 10");
  14: });