Make Your Code Modular Buddy! (Angular.js Modules)

Unlike the Hello World Program, in real life an enterprise level application gets bigger and bigger day by day as the client's requirements flown in from here and there. Managing these kind of applications are easy when some heavyweight enterprise languages like C#, Java etc. are there for you. These heavyweight languages provides some features, where a client side language like JavaScript often lakes. Features like Class and Namespace are absent in JavaScript. But since every problem has a solution, with the help of JavaScript functions we can have both of those features. The simplest way to create a namespace in JavaScript is to use a self-invocating anonymous function. Likewise we can use a factory function returns a singleton object. But enough of these advance features. Let's see what Angular provides us to implement the concept of Namespace and Class. Angular has a feature called module by which we can introduce Namespaces in our code. By using modules we can keep the global namespace [Global Scope] clean. This makes testing our code easier and also sharing of code between applications easier [You can make your own modules and use it in different applications]. For an example let's create a simple module and encapsulate some basic functionalities into the module.

Since separating the scripts from the HTML files is a good practice. A simple Anguler module can be written as follows in the app.js file:


var app = angular.module('app', []);
app.controller('messageController', function($scope) {
    $scope.data = {
        message: "Fiyaz Hasan"
    };
});


app.controller('mathController',function($scope) {
    $scope.data = {
        number: 9,
        squareRoot: function () {
            return Math.sqrt(this.number);
        }
    };
});

The important part here is that we declared an app Namespace with the help of angular.module('app', []); Here the first parameter represents the Namespace identifier and the empty [] third braces means that we can inject dependencies into the module.[More about dependencies will be discussed later]. Except that nothing is so special here. All I did is I created two application specific controllers that can only be accessed when a DOM references the module.

The controllers serve the same functionality as the previous post's controllers serve. Now goes the HTML layout,


<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
    <title>Angular Module</title>
</head>
<body>
    <div ng-controller="messageController">
        <input type="text" ng-model="data.message" />
        <h1>{{data.message}}</h1>
    </div>
    <div ng-controller="mathController">
        <input type="text" ng-model="data.number" />
        <h1>{{data.squareRoot()}}</h1>
    </div>
    <script src="scripts/angular.js"></script>
    <script src="scripts/App/app.js"></script>
</body>
</html>

As you can see all are as before except at the top I have referenced the app module into the ng-app directive. And we are done. Now our HTML document will only responds to the different functionality described in the app module.

Now let's talk about how we have kept our global namespace clean by using module. To show an example I've created another Angular module called app2 and the script is as follows,


var app2 = angular.module('app2', []);
app2.controller('messageController', function ($scope) {
    $scope.data = {
        message: "Circle circumference"
    };
});


app2.controller('mathController', function ($scope) {
    $scope.data = {
        radius: 3,
        circumference: function () {
            return 2 * Math.PI * this.radius;
        }
    };
});

Up in the script again I've two controllers whose names are as same as app modules controller but in app2 module they serve different purposes. As you can see the first one [messageController] is identical to the previous [messageController] one in the app module where the second controller [mathController] returns the circumference of a circle with a given radius.

Again I've created another HTML file called index2.html and the layout is like this,


<!DOCTYPE html>
<html lang="en" ng-app="app2">
<head>
    <title>Angular Module</title>
</head>
<body>
    <div ng-controller="messageController">
        <input type="text" ng-model="data.message" />
        <h1>{{data.message}}</h1>
    </div>
    <div ng-controller="mathController">
        <input type="text" ng-model="data.radius" />
        <h1>{{data.circumference()}}</h1>
    </div>
    <script src="scripts/angular.js"></script>
    <script src="scripts/App/app.js"></script>
</body>
</html>

From the script shown above I guess you've already figured out the rest. In app2 module we have those two controllers with the same name again as we have in the app module but I kept the controller name same. As we can see that identical controllers didn't come in each others way because they are attached to different modules. Since two HTML documents reference two different modules the behavior that the application gets depend on the different module functionalities. The outputs are shown below.

OUTPUT: