Use facilities provided by the JS language to have a clean code
How to minimize the number of global variables ?
Wrap Angular components in an IIFE (Immediately-Invoked Function Expression).
Components declared in an IIFE don’t become global variables.
How to avoid to declare JS variables never used ?
The « use strict » directive is new in JavaScript 1.8.5 (ECMAScript version 5).
It is not a statement, but a literal expression, ignored by earlier versions of JavaScript.
The purpose of « use strict » is to indicate that the code should be executed in « strict mode ».
With strict mode, undeclared variables will raise Javascript errors at runtime.
How to declare base elements of an AngularJS application : module, services, controller and navigation rules?
How to declare the main module of the application that uses extension modules ?
In a web application, you declare your main AngularJS module with the syntax :
angular.module('moduleName',['moduleDependencyOne','moduleDependencyTwo', 'moduleDependencyThree']) |
You may notice the second argument of the module constructor that is an array listing module dependencies we want to load.
In AngularJs, you have some native/embedded services which you don’t need to declare modules for them to use them.
These services are directly coded in the framework (the angular.js file).
For example Angular service components such as ‘$http’, ‘$q’, ‘$window’ are provided by Angular module for service components. So, you don’t need to declare this module in the array of dependencies.
Other services are not part of core AngularJS framework. So, as for angular.js file, you had to add them in the list of javascript files you want to load to the startup of your default web page.
For example, if you want to use the angular-cookies and router services, you have to declare it in your index.html page :
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-cookies.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular-route.js"></script> |
But it is not enough because contrary to native services, extension services, in order to be able to use services provided by AngularJS extension libraries in your angular application code,, you must declare them as dependencies such as :
angular.module('myApp',['ngCookies','ngRoute']); |
How to get the applicative module to enhance it (adding services, controllers, navigation rules, etc..)
angular.module(‘myApp’,[]) instantiates the myApp module.
angular.module(‘myApp’) retrieve an existing myApp module.
Notice the difference : the constructor version has a String array, the getter version has not a String array.
So, in your angularJS applicative code, angular.module(‘myApp’,[]) have to be written once and once only while angular.module(‘myApp’) may be called so many times as needed in order to add components to our module.
For example, you can declare your main module and add a controller to it in this way :
angular.module('myApp',[]); // instantiating the myApp module angular.module('myApp').controller('GroupController', GroupController); // retrieving the myApp module and adding GroupController controller to it. |
How to declare a service?
A service must not be visible to the html page since it’s a low level component used by Angular controllers.
So, we must declare it only in the javascript side.
For example, here UserService, a service to create a user.
angular.module('myApp') .factory('UserService', UserService); function UserService($http, $q, $window){ var url = 'api/employees'; return { createUser: function(user){ $http.defaults.headers.post["Content-Type"] = "application/json"; return $http.post(url, user) .then( function(response){ return response.data; }, function(errResponse){ return $q.reject(errResponse); } ); }, } |
You can notice that in AngularJS, service terminology is not used to register the service :
angular.module('myApp') .factory('UserService', UserService); |
Indeed, you use the factory() method of the module object to store the function representing the service.
Besides, semantically, a service is a function and not a component. That’s why in the UserService constructor, we return a function containing all needed functions for our service class (here, a single function since it’s a simple example).
How to declare a controller which depends on a service component ?
We will declare UserController, a controller with a submit function which delegates the processing to UserService service. In general, it’s the way controllers work.
In the html side :
<div ng-controller="UserController as ctrl" > <form ng-submit="ctrl.submit()"> <!-- other input data... --> </form> </div> |
The MyController as ctrl syntax (which is appeared with the 1.2 version) should be favored since it avoid using the $scope object in the javascript code.
$scope should be explicitly used only when we have not the choice since it’s a very powerful and complex object that not mastered may have serious side effects.
If you know Java, You can do a parallel between the explicitly use of $scope and the explicitly use of synchronization mechanisms in Java such as the synchronized keyword.
Both are powerful, complex and may have side effects if not mastered. So you should use only when it’s unavoidable.
In the javascript side :
angular.module('myApp') .controller('UserController', UserController); function UserController(UserService) { var self = this; self.submit = function() { UserService.doProcessing(); } } |
How to declare navigation rules ?
You can declare them in a dedicated file or in the file instantiating the main module.
Using one or the other way is not very important since the main module file should not contain any processing and so should go on to be readable despite adding the navigation rules inside.
angular.module('myApp',['ngCookies','ngMessages', 'ngRoute']) .config(['$routeProvider', function ($routeProvider){ $routeProvider. when('/',{ templateUrl: 'pages/manage-employees.html', controller: 'UserController', }) .when('/manageUserGroups',{ templateUrl: 'pages/manage-groups.html', controller: 'UserController', }) .when('/manageEmployees',{ templateUrl: 'pages/manage-employees.html', controller: 'UserController', }) .otherwise({ redirectTo: 'pages/toto.html' }); }] ); |