Angular Js
Angular Js
Angular Js
#angularjs
Table of Contents
About 1
Remarks 2
Versions 2
Examples 9
Getting Started 9
ng-app 14
Directives 14
Minification in Angular 15
Examples 19
Remarks 23
Examples 23
How can you limit the scope on a directive and why would you do this? 26
Introduction 28
Examples 28
The Static View with controller 28
mvc demo 28
Examples 29
Directory Structure 29
Examples 32
Properties 35
Remarks 39
Examples 39
= two-way binding. 39
Examples 42
Introduction 49
Examples 49
Examples 50
ngRepeat 50
ngOptions 55
ngModel 57
ngClass 58
ngIf 58
JavaScript 58
View 59
Function Promise 59
ngDisabled 60
ngDblclick 61
ngClick 62
ngRequired 63
ng-model-options 64
ngCloak 65
ngInclude 65
ngSrc 65
ngPattern 66
ngValue 66
ngCopy 67
ngPaste 67
ngHref 67
ngList 68
Examples 69
angular.equals 69
angular.isString 69
angular.isArray 69
angular.merge 70
angular.isDate 71
angular.isNumber 71
angular.isFunction 72
angular.toJson 72
angular.fromJson 72
angular.noop 73
angular.isObject 73
angular.isElement 74
angular.copy 74
angular.identity 75
angular.forEach 75
Parameters 77
Remarks 78
Examples 78
What’s a component? 78
Components In angular JS 80
Remarks 82
Examples 82
Use cases 82
Syntax 85
Examples 85
Creating Controllers 87
Nested Controllers 90
Examples 91
Controller 91
Introduction 92
Parameters 92
Examples 94
Examples 104
example.js 104
example.html 104
Examples 106
Examples 108
Syntax 114
Remarks 114
Examples 114
Syntax 117
Remarks 117
Examples 117
Injections 117
Syntax 120
Examples 120
Examples 123
Examples 129
Parameters 131
Examples 131
$scope.$emit 131
$scope.$broadcast 131
Syntax : 132
Examples 136
Javascript 136
HTML 137
Examples 141
ngMessages 143
Example 143
Examples 146
Remarks 149
Examples 149
Introduction 152
Examples 152
Remarks 155
Examples 155
Usage 155
UI-Router: 156
ngRoute: 156
Introduction 158
Examples 158
Conclusion 160
Examples 162
Modules 162
Modules 162
Examples 164
1. String 164
2. Object 164
3. Array 165
Introduction 166
Syntax 166
Parameters 166
Remarks 166
Examples 166
Introduction 169
Syntax 169
Examples 169
Introduction 170
Examples 170
ng-view 170
Examples 172
Examples 174
Remarks 178
Examples 178
Examples 180
4) Watchers 182
Watchers 185
ng-if 187
ng-show 187
Example 187
Conclusion 188
Always deregister listeners registered on other scopes other than the current scope 188
Syntax 190
Remarks 190
Examples 190
Constant 190
Value 191
Factory 191
Service 192
Provider 192
Remarks 194
Examples 194
Examples 198
Examples 205
In controller : 205
Remarks 206
Examples 206
Introduction 208
Examples 208
Introduction 212
Examples 212
Remarks 214
Examples 214
Remarks 220
Examples 220
Examples 225
Syntax 227
Examples 227
Credits 232
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: angularjs
It is an unofficial and free AngularJS ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official AngularJS.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with AngularJS
Remarks
AngularJS is a web application framework designed to simplify rich client-side application
development. This documentation is for Angular 1.x, the predecessor of the more modern Angular
2 or see the Stack Overflow documentation for Angular 2.
Versions
1.6.5 2017-07-03
1.6.4 2017-03-31
1.6.3 2017-03-08
1.6.2 2017-02-07
1.5.11 2017-01-13
1.6.1 2016-12-23
1.5.10 2016-12-15
1.6.0 2016-12-08
1.6.0-rc.2 2016-11-24
1.5.9 2016-11-24
1.6.0-rc.1 2016-11-21
1.6.0-rc.0 2016-10-26
1.2.32 2016-10-11
1.4.13 2016-10-10
1.2.31 2016-10-10
1.5.8 2016-07-22
1.2.30 2016-07-21
1.5.7 2016-06-15
https://riptutorial.com/ 2
Version Release Date
1.4.12 2016-06-15
1.5.6 2016-05-27
1.4.11 2016-05-27
1.5.5 2016-04-18
1.5.4 2016-04-14
1.5.3 2016-03-25
1.5.2 2016-03-19
1.4.10 2016-03-16
1.5.1 2016-03-16
1.5.0 2016-02-05
1.5.0-rc.2 2016-01-28
1.4.9 2016-01-21
1.5.0-rc.1 2016-01-16
1.5.0-rc.0 2015-12-09
1.4.8 2015-11-20
1.5.0-beta.2 2015-11-18
1.4.7 2015-09-30
1.3.20 2015-09-30
1.2.29 2015-09-30
1.5.0-beta.1 2015-09-30
1.5.0-beta.0 2015-09-17
1.4.6 2015-09-17
1.3.19 2015-09-17
1.4.5 2015-08-28
1.3.18 2015-08-19
https://riptutorial.com/ 3
Version Release Date
1.4.4 2015-08-13
1.4.3 2015-07-15
1.3.17 2015-07-07
1.4.2 2015-07-07
1.4.1 2015-06-16
1.3.16 2015-06-06
1.4.0 2015-05-27
1.4.0-rc.2 2015-05-12
1.4.0-rc.1 2015-04-24
1.4.0-rc.0 2015-04-10
1.3.15 2015-03-17
1.4.0-beta.6 2015-03-17
1.4.0-beta.5 2015-02-24
1.3.14 2015-02-24
1.4.0-beta.4 2015-02-09
1.3.13 2015-02-09
1.3.12 2015-02-03
1.4.0-beta.3 2015-02-03
1.3.11 2015-01-27
1.4.0-beta.2 2015-01-27
1.4.0-beta.1 2015-01-20
1.3.10 2015-01-20
1.3.9 2015-01-15
1.4.0-beta.0 2015-01-14
1.3.8 2014-12-19
https://riptutorial.com/ 4
Version Release Date
1.2.28 2014-12-16
1.3.7 2014-12-15
1.3.6 2014-12-09
1.3.5 2014-12-02
1.3.4 2014-11-25
1.2.27 2014-11-21
1.3.3 2014-11-18
1.3.2 2014-11-07
1.3.1 2014-10-31
1.3.0 2014-10-14
1.3.0-rc.5 2014-10-09
1.2.26 2014-10-03
1.3.0-rc.4 2014-10-02
1.3.0-rc.3 2014-09-24
1.2.25 2014-09-17
1.3.0-rc.2 2014-09-17
1.2.24 2014-09-10
1.3.0-rc.1 2014-09-10
1.3.0-rc.0 2014-08-30
1.2.23 2014-08-23
1.3.0-beta.19 2014-08-23
1.2.22 2014-08-12
1.3.0-beta.18 2014-08-12
1.2.21 2014-07-25
1.3.0-beta.17 2014-07-25
https://riptutorial.com/ 5
Version Release Date
1.3.0-beta.16 2014-07-18
1.2.20 2014-07-11
1.3.0-beta.15 2014-07-11
1.2.19 2014-07-01
1.3.0-beta.14 2014-07-01
1.3.0-beta.13 2014-06-16
1.3.0-beta.12 2014-06-14
1.2.18 2014-06-14
1.3.0-beta.11 2014-06-06
1.2.17 2014-06-06
1.3.0-beta.10 2014-05-24
1.3.0-beta.9 2014-05-17
1.3.0-beta.8 2014-05-09
1.3.0-beta.7 2014-04-26
1.3.0-beta.6 2014-04-22
1.2.16 2014-04-04
1.3.0-beta.5 2014-04-04
1.3.0-beta.4 2014-03-28
1.2.15 2014-03-22
1.3.0-beta.3 2014-03-21
1.3.0-beta.2 2014-03-15
1.3.0-beta.1 2014-03-08
1.2.14 2014-03-01
1.2.13 2014-02-15
1.2.12 2014-02-08
https://riptutorial.com/ 6
Version Release Date
1.2.11 2014-02-03
1.2.10 2014-01-25
1.2.9 2014-01-15
1.2.8 2014-01-10
1.2.7 2014-01-03
1.2.6 2013-12-20
1.2.5 2013-12-13
1.2.4 2013-12-06
1.2.3 2013-11-27
1.2.2 2013-11-22
1.2.1 2013-11-15
1.2.0 2013-11-08
1.2.0-rc.3 2013-10-14
1.2.0-rc.2 2013-09-04
1.0.8 2013-08-22
1.2.0rc1 2013-08-13
1.0.7 2013-05-22
1.1.5 2013-05-22
1.0.6 2013-04-04
1.1.4 2013-04-04
1.0.5 2013-02-20
1.1.3 2013-02-20
1.0.4 2013-01-23
1.1.2 2013-01-23
1.1.1 2012-11-27
https://riptutorial.com/ 7
Version Release Date
1.0.3 2012-11-27
1.1.0 2012-09-04
1.0.2 2012-09-04
1.0.1 2012-06-25
1.0.0 2012-06-14
v1.0.0rc12 2012-06-12
v1.0.0rc11 2012-06-11
v1.0.0rc10 2012-05-24
v1.0.0rc9 2012-05-15
v1.0.0rc8 2012-05-07
v1.0.0rc7 2012-05-01
v1.0.0rc6 2012-04-21
v1.0.0rc5 2012-04-12
v1.0.0rc4 2012-04-05
v1.0.0rc3 2012-03-30
v1.0.0rc2 2012-03-21
g3-v1.0.0rc1 2012-03-14
g3-v1.0.0-rc2 2012-03-16
1.0.0rc1 2012-03-14
0.10.6 2012-01-17
0.10.5 2011-11-08
0.10.4 2011-10-23
0.10.3 2011-10-14
0.10.2 2011-10-08
0.10.1 2011-09-09
https://riptutorial.com/ 8
Version Release Date
0.10.0 2011-09-02
0.9.19 2011-08-21
0.9.18 2011-07-30
0.9.17 2011-06-30
0.9.16 2011-06-08
0.9.15 2011-04-12
0.9.14 2011-04-01
0.9.13 2011-03-14
0.9.12 2011-03-04
0.9.11 2011-02-09
0.9.10 2011-01-27
0.9.9 2011-01-14
0.9.7 2010-12-11
0.9.6 2010-12-07
0.9.5 2010-11-25
0.9.4 2010-11-19
0.9.3 2010-11-11
0.9.2 2010-11-03
0.9.1 2010-10-27
0.9.0 2010-10-21
Examples
Getting Started
<!DOCTYPE html>
<html ng-app>
https://riptutorial.com/ 9
<head>
<title>Hello, Angular</title>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
</head>
<body ng-init="name='World'">
<label>Name</label>
<input ng-model="name" />
<span>Hello, {{ name }}!</span>
<p ng-bind="name"></p>
</body>
</html>
Live demo
When you open the file with a browser, you will see an input field followed by the text Hello,
World!. Editing the value in the input will update the text in real-time, without the need to refresh
the whole page.
Explanation:
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
2. Define the HTML document as an Angular application with the ng-app directive
<html ng-app>
Note that ng-init should be used for demonstrative and testing purposes only. When building
an actual application, controllers should initialize the data.
4. Bind data from the model to the view on HTML controls. Bind an <input> to the name property
with ng-model
6. Another way of binding the name property is using ng-bind instead of handlebars"{{ }}"
<span ng-bind="name"></span>
The last three steps establish the two way data-binding. Changes made to the input update the
https://riptutorial.com/ 10
model, which is reflected in the view.
There is a difference between using handlebars and ng-bind. If you use handlebars, you might see
the actual Hello, {{name}} as the page loads before the expression is resolved (before the data is
loaded) whereas if you use ng-bind, it will only show the data when the name is resolved. As an
alternative the directive ng-cloak can be used to prevent handlebars to display before it is
compiled.
<!DOCTYPE html>
<html ng-app="myDemoApp">
<head>
<style>.started { background: gold; }</style>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script>
function MyDataService() {
return {
getWorlds: function getWorlds() {
return ["this world", "another world"];
}
};
}
function DemoController(worldsService) {
var vm = this;
vm.messages = worldsService.getWorlds().map(function(w) {
return "Hello, " + w + "!";
});
}
https://riptutorial.com/ 11
Live Demo
1. ng-app="myDemoApp", the ngApp directive that bootstraps the application and tells angular that
a DOM element is controlled by a specific angular.module named "myDemoApp";
2. <script src="angular.min.js"> is the first step in bootstrapping the AngularJS library;
Three functions (MyDataService, DemoController, and startup) are declared, which are used (and
explained) below.
3. angular.module(...) used with an array as the second argument creates a new module. This
array is used to supply a list of module dependencies. In this example we chain calls on the
result of the module(...) function;
4. .service(...) creates an Angular Service and returns the module for chaining;
5. .controller(...) creates an Angular Controller and returns the module for chaining;
6. .config(...) Use this method to register work which needs to be performed on module
loading.
7. .run(...) makes sure code is run at startup time and takes an array of items as a parameter.
Use this method to register work which should be performed when the injector is done
loading all modules.
• the first item is letting Angular know that the startup function requires the built-in
$rootScope service to be injected as an argument;
• the second item is letting Angular know that the startup function requires the built-in
$window service to be injected as an argument;
• the last item in the array, startup, is the actual function to run on startup;
8. ng-class is the ngClass directive to set a dynamic class, and in this example utilizes
hasStarted on the $rootScope dynamically
9. ng-cloak is a directive to prevent the unrendered Angular html template (e.g. "{{ msg }}") to
be briefly shown before Angular has fully loaded the application.
10. ng-controller is the directive that asks Angular to instantiate a new controller of specific
name to orchestrate that part of the DOM;
11. ng-repeat is the directive to make Angular iterate over a collection and clone a DOM template
for each item;
12. {{ msg }} showcases interpolation: on-the-spot rendering of a part of the scope or controller;
As Angular uses HTML to extend a web page and plain Javascript to add logic, it makes it easy to
create a web page using ng-app, ng-controller and some built-in directives such as ng-if, ng-
repeat, etc. With the new controllerAs syntax, newcomers to Angular users can attach functions
and data to their controller instead of using $scope.
https://riptutorial.com/ 12
However, sooner or later, it is important to understand what exactly this $scope thing is. It will keep
showing up in examples so it is important to have some understanding.
<div ng-app="myApp">
<h1>Hello {{ name }}</h1>
</div>
The answer is that Angular creates a $rootScope object. This is simply a regular Javascript object
and so name is a property on the $rootScope object:
angular.module("myApp", [])
.run(function($rootScope) {
$rootScope.name = "World!";
});
And just as with global scope in Javascript, it's usually not such a good idea to add items to the
global scope or $rootScope.
Of course, most of the time, we create a controller and put our required functionality into that
controller. But when we create a controller, Angular does it's magic and creates a $scope object for
that controller. This is sometimes referred to as the local scope.
<div ng-app="myApp">
<div ng-controller="MyController">
<h1>Hello {{ name }}</h1>
</div>
</div>
would allow the local scope to be accessible via the $scope parameter.
angular.module("myApp", [])
.controller("MyController", function($scope) {
$scope.name = "Mr Local!";
});
A controller without a $scope parameter may simply not need it for some reason. But it is important
to realize that, even with controllerAs syntax, the local scope exists.
https://riptutorial.com/ 13
Then via the prototype chain, a child controller could access that same model locally with
$scope.model.
None of this is initially evident, as it's just Angular doing its magic in the background. But
understanding $scope is an important step in getting to know how Angular works.
Angular 1 is at heart a DOM compiler. We can pass it HTML, either as a template or just as a
regular web page, and then have it compile an app.
We can tell Angular to treat a region of the page as an expression using the {{ }} handlebars style
syntax. Anything between the curly braces will be compiled, like so:
{{ 'Hello' + 'World' }}
HelloWorld
ng-app
We tell Angular which portion of our DOM to treat as the master template using the ng-app directive
. A directive is a custom attribute or element that the Angular template compiler knows how to deal
with. Let's add an ng-app directive now:
<html>
<head>
<script src="/angular.js"></script>
</head>
<body ng-app>
{{ 'Hello' + 'World' }}
</body>
</html>
I've now told the body element to be the root template. Anything in it will be compiled.
Directives
Directives are compiler directives. They extend the capabilities of the Angular DOM compiler. This
is why Misko, the creator of Angular, describes Angular as:
"What a web browser would have been had it been built for web applications.
We literally create new HTML attributes and elements, and have Angular compile them into an
app. ng-app is a directive that simply turns on the compiler. Other directives include:
https://riptutorial.com/ 14
, which conditionally hides an element, and
• <form>, which adds additional behaviour to a standard HTML form element.
Angular comes with around 100 built-in directives which allow you to accomplish most common
tasks. We can also write our own, and these will be treated in the same way as the built in
directives.
We build an Angular app out of a series of directives, wired together with HTML.
Minification in Angular
What is Minification ?
It is the process of removing all unnecessary characters from source code without changing its
functionality.
Normal Syntax
If we use normal angular syntax for writing a controller then after minifiying our files it going to
break our functionality.
var app=angular.module("mainApp",[]);app.controller("FirstController",function(e){e.name=
'Hello World !'})
Here, minification removed unnecessary spaces and the $scope variable from code. So when we
use this minified code then its not going to print anything on view. Because $scope is a crucial part
between controller and view, which is now replaced by the small 'e' variable. So when you run the
application it is going to give Unknown Provider 'e' dependency error.
There are two ways of annotating your code with service name information which are minification
safe:
https://riptutorial.com/ 15
FirstController.$inject = ['$scope'];
var FirstController = function($scope) {
$scope.message = 'Hello World !';
}
var
app=angular.module("mainApp",[]);app.controller("FirstController",["$scope",function(a){a.message="Hell
World !"}]);
Here, angular will consider variable 'a' to be treated as $scope, and It will display output as 'Hello
World !'.
There are a lot of good video tutorials for the AngularJS framework on egghead.io
https://riptutorial.com/ 16
• https://egghead.io/courses/angularjs-app-from-scratch-getting-started
https://riptutorial.com/ 17
• https://egghead.io/courses/angularjs-application-architecture
• https://egghead.io/courses/angular-material-introduction
• https://egghead.io/courses/building-an-angular-1-x-ionic-application
• https://egghead.io/courses/angular-and-webpack-for-modular-applications
• https://egghead.io/courses/angularjs-authentication-with-jwt
• https://egghead.io/courses/angularjs-data-modeling
• https://egghead.io/courses/angular-automation-with-gulp
• https://egghead.io/courses/learn-protractor-testing-for-angularjs
• https://egghead.io/courses/ionic-quickstart-for-windows
• https://egghead.io/courses/build-angular-1-x-apps-with-redux
• https://egghead.io/courses/using-angular-2-patterns-in-angular-1-x-apps
https://riptutorial.com/ 18
Chapter 2: $http request
Examples
Using $http inside a controller
The $http service is a function which generates an HTTP request and returns a promise.
General Usage
appName.controller('controllerName',
['$http', function($http){
Shortcut Methods
$http service also has shortcut methods. Read about http methods here
Syntax
Shortcut Methods
• $http.get
https://riptutorial.com/ 19
• $http.head
• $http.post
• $http.put
• $http.delete
• $http.jsonp
• $http.patch
HTTP requests are widely used repeatedly across every web app, so it is wise to write a method
for each common request, and then use it in multiple places throughout the app.
Create a httpRequestsService.js
httpRequestsService.js
return {
// function that performs a basic get request
getName: function(){
// make sure $http is injected
return $http.get("/someAPI/names")
.then(function(response) {
// return the result as a promise
return response;
}, function(response) {
// defer the promise
return $q.reject(response.data);
});
},
The service above will perform a get request inside the service. This will be available to any
controller where the service has been injected.
Sample usage
appName.controller('controllerName',
['httpRequestsService', function(httpRequestsService){
https://riptutorial.com/ 20
}])
Using this approach we can now use httpRequestsService.js anytime and in any controller.
The $http requests require time which varies depending on the server, some may take a few
milliseconds, and some may take up to a few seconds. Often the time required to retrieve the data
from a request is critical. Assuming the response value is an array of names, consider the
following example:
Incorrect
$scope.names = [];
$http({
method: 'GET',
url: '/someURL'
}).then(function successCallback(response) {
$scope.names = response.data;
},
function errorCallback(response) {
alert(response.status);
});
Accessing $scope.names[0] right below the $http request will often throw an error - this line of code
executes before the response is received from the server.
Correct
$scope.names = [];
$http({
method: 'GET',
url: '/someURL'
}).then(function successCallback(response) {
$scope.names = response.data;
},
function errorCallback(response) {
alert(response.status);
});
Using the $watch service we access the $scope.names array only when the response is received.
During initialization, the function is called even though $scope.names was initialized before,
therefore checking if the newVal.length is different than 0 is necessary. Be aware - any changes
made to $scope.names will trigger the watch function.
https://riptutorial.com/ 21
Read $http request online: https://riptutorial.com/angularjs/topic/3620/-http-request
https://riptutorial.com/ 22
Chapter 3: Angular $scopes
Remarks
Angular uses a tree of scopes to bind the logic (from controllers, directives, etc) to the view and
are the primary mechanism behind change detection in AngularJS. A more detailed reference for
scopes can be found at docs.angularjs.org
The root of the tree is accessible as via inject-able service $rootScope. All child $scopes inherit
the methods and properties of their parent $scope, allowing children access to methods without
the use of Angular Services.
Examples
Basic Example of $scope inheritance
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' };
}]);
In this example, the ng-repeat directive creates a new scope for each of its newly created children.
These created scopes are children of their parent scope (in this case the scope created by
myController), and therfore, they inherit all of its proporties, such as person.
In javascript, assigning a non-primitive value (Such as Object, Array, Function, and many more),
keeps a reference (an address in the memory) to the assigned value.
Assigning a primitive value (String, Number, Boolean, or Symbol) to two different variables, and
changing one, won't change both:
var x = 5;
var y = x;
y = 6;
console.log(y === x, x, y); //false, 5, 6
But with a non-primitive value, since both variables are simply keeping references to the same
object, changing one variable will change the other:
https://riptutorial.com/ 23
var x = { name : 'John Doe' };
var y = x;
y.name = 'Jhon';
console.log(x.name === y.name, x.name, y.name); //true, John, John
In angular, when a scope is created, it is assigned all of its parent's properties However, changing
properties afterwards will only affect the parent scope if it is a non-primitive value:
angular.module('app', [])
.controller('myController', ['$scope', function($scope){
$scope.person = { name: 'John Doe' }; //non-primitive
$scope.name = 'Jhon Doe'; //primitive
}])
.controller('myController1', ['$scope', function($scope){}]);
Remember: in Angular scopes can be created in many ways (such as built-in or custom directives,
or the $scope.$new() function), and keeping track of the scope tree is probably impossible.
Using only non-primitive values as scope properties will keep you on the safe side (unless you
need a property to not inherit, or other cases where you are aware of scope inheritance).
Be careful, this approach might be considered as a bad design for angular apps, since it requires
programmers to remember both where functions are placed in the scope tree, and to be aware of
scope inheritance. In many cases it would be preferred to inject a service (Angular practice - using
scope inheritance vs injection.
This example only show how scope inheritance could be used for our needs, and the how you
could take advantage of it, and not the best practices of designing an entire app.
In some cases, we could take advantage of scope inheritance, and set a function as a property of
the rootScope. This way - all of the scopes in the app (except for isolated scopes) will inherit this
function, and it could be called from anywhere in the app.
angular.module('app', [])
.run(['$rootScope', function($rootScope){
var messages = []
$rootScope.addMessage = function(msg){
messages.push(msg);
}
}]);
<div ng-app="app">
https://riptutorial.com/ 24
<a ng-click="addMessage('hello world!')">it could be accsessed from here</a>
<div ng-include="inner.html"></div>
</div>
inner.html:
<div>
<button ng-click="addMessage('page')">and from here to!</button>
</div>
Like normal HTML elements, it is possible for $scopes to have their own events. $scope events
can be subscribed to using the following manner:
If you need unregister an event listener, the $on function will return an unbinding function. To
continue with the above example:
There are two ways of triggering your own custom $scope event $broadcast and $emit. To notify
the parent(s) of a scope of a specific event, use $emit
The above example will trigger any event listeners for my-event on the parent scope and will
continue up the scope tree to $rootScope unless a listener calls stopPropagation on the event.
Only events triggered with $emit may call stopPropagation
The reverse of $emit is $broadcast, which will trigger any event listeners on all child scopes in
the scope tree that are children of the scope that called $broadcast.
While declaring a function in the $rootscope has it's advantages, we can also declare a $scope
function any part of the code that is injected by the $scope service. Controller, for instance.
Controller
https://riptutorial.com/ 25
myApp.controller('myController', ['$scope', function($scope){
$scope.myFunction = function () {
alert("You are in myFunction!");
};
}]);
Now you can call your function from the controller using:
$scope.myfunction();
<div ng-controller="myController">
<button ng-click="myFunction()"> Click me! </button>
</div>
Directive
myApp.directive('triggerFunction', function() {
return {
scope: {
triggerFunction: '&'
},
link: function(scope, element) {
element.bind('mouseover', function() {
scope.triggerFunction();
});
}
};
});
<div ng-controller="myController">
<button trigger-function="myFunction()"> Hover over me! </button>
</div>
Of course, you can use ngMouseover for the same thing, but what's special about directives is that
you can customize them the way you want. And now you know how to use your $scope functions
inside them, be creative!
How can you limit the scope on a directive and why would you do this?
Scope is used as the "glue" that we use to communicate between the parent controller, the
directive, and the directive template. Whenever the AngularJS application is bootstrapped, a
rootScope object is created. Each scope created by controllers, directives and services are
prototypically inherited from rootScope.
Yes, we can limit the scope on a directive . We can do so by creating an isolated scope for
https://riptutorial.com/ 26
directive.
Directives with the new isolated scope: When we create a new isolated scope then it will not be
inherited from the parent scope. This new scope is called Isolated scope because it is completely
detached from its parent scope. Why? should we use isolated scope: We should use isolated
scope when we want to create a custom directive because it will make sure that our directive is
generic, and placed anywhere inside the application. Parent scope is not going to interfere with the
directive scope.
app.controller("Ctrl1",function($scope){
$scope.name = "Prateek";
$scope.reverseName = function(){
$scope.name = $scope.name.split('').reverse().join('');
};
});
app.directive("myDirective", function(){
return {
restrict: "EA",
scope: {},
template: "<div>Your name is : {{name}}</div>"+
"Change your name : <input type='text' ng-model='name'/>"
};
});
There’re 3 types of prefixes AngularJS provides for isolated scope these are :
All these prefixes receives data from the attributes of the directive element like :
<div my-directive
class="directive"
name="{{name}}"
reverse="reverseName()"
color="color" >
</div>
https://riptutorial.com/ 27
Chapter 4: Angular MVC
Introduction
In AngularJS the MVC pattern is implemented in JavaScript and HTML. The view is defined in
HTML, while the model and controller are implemented in JavaScript. There are several ways that
these components can be put together in AngularJS but the simplest form starts with the view.
Examples
The Static View with controller
mvc demo
Hello World
https://riptutorial.com/ 28
Chapter 5: Angular Project - Directory
Structure
Examples
Directory Structure
A common question among new Angular programmers - "What should be the structure of the
project?". A good structure helps toward a scalable application development. When we start a
project we have two choices, Sort By Type (left) and Sort By Feature (right). The second is
better, especially in large applications, the project becomes a lot easier to manage.
https://riptutorial.com/ 29
The application is organized by the files' type.
• Advantage - Good for small apps, for programmers only starting to use Angular, and is easy
to convert to the second method.
• Disadvantage - Even for small apps it starts to get more difficult to find a specific file. For
instance, a view and it's controller are in two seperate folders.
All of the layout views and controllers go in the layout folder, the admin content goes in the admin
folder, and so on.
• Advantage - When looking for a section of code determining a certain feature it's all located
in one folder.
• Disadvantage - Services are a bit different as they “service” many features.
You can read more about it on Angular Structure: Refactoring for Growth
https://riptutorial.com/ 30
Credit to: Angular Style Guide
https://riptutorial.com/ 31
Chapter 6: Angular promises with $q service
Examples
Using $q.all to handle multiple promises
You can use the $q.all function to call a .then method after an array of promises has been
successfully resolved and fetch the data they resolved with.
Example:
JS:
$scope.data = []
$q.all([
$http.get("data.json"),
$http.get("more-data.json"),
]).then(function(responses) {
$scope.data = responses.map((resp) => resp.data);
});
The above code runs $http.get 2 times for data in local json files, when both get method complete
they resolve their associated promises, when all the promises in the array are resolved, the .then
method starts with both promises data inside the responses array argument.
The data is then mapped so it could be shown on the template, we can then show
HTML:
<ul>
<li ng-repeat="d in data">
<ul>
<li ng-repeat="item in d">{{item.name}}: {{item.occupation}}</li>
</ul>
</li>
</ul>
JSON:
[{
"name": "alice",
"occupation": "manager"
}, {
"name": "bob",
"occupation": "developer"
}]
https://riptutorial.com/ 32
The $q constructor function is used to create promises from asynchronous APIs that use callbacks
to return results.
The constructor function receives a function that is invoked with two arguments, resolve and reject
that are functions which are used to either resolve or reject the promise.
Example 1:
The above example creates a promise from the WindowTimers.setTimeout API. The AngularJS
framework provides a more elaborate version of this function. For usage, see the AngularJS
$timeout Service API Reference.
Example 2:
$scope.divide = function(a, b) {
return $q(function(resolve, reject) {
if (b===0) {
return reject("Cannot devide by 0")
} else {
return resolve(a/b);
}
});
}
The above code showing a promisified division function, it will return a promise with the result or
reject with a reason if the calculation is impossible.
$scope.divide(7, 2).then(function(result) {
// will return 3.5
}, function(err) {
// will not run
})
$scope.divide(2, 0).then(function(result) {
// will not run as the calculation will fail on a divide by 0
}, function(err) {
https://riptutorial.com/ 33
// will return the error string.
})
We can use $q to defer operations to the future while having a pending promise object at the
present, by using $q.defer we create a promise that will either resolve or reject in the future.
This method is not equivalent of using the $q constructor, as we use $q.defer to promisify an
existing routine that may or may not return (or had ever returned) a promise at all.
Example:
// and then
runAnimation.then(function(status) {}, function(error) {})
1. Be sure you always return a the deferred.promise object or risk an error when invoking .then
2. Make sure you always resolve or reject your deferred object or .then may not run and you
risk a memory leak
$q is a built-in service which helps in executing asynchronous functions and using their return
values(or exception) when they are finished with processing.
$q is integrated with the $rootScope.Scope model observation mechanism, which means faster
propagation of resolution or rejection into your models and avoiding unnecessary browser
repaints, which would result in flickering UI.
In our example, we call our factory getMyData, which return a promise object. If the object is
resolved, it returns a random number. If it is rejected, it return a rejection with an error message
after 2 seconds.
In Angular factory
https://riptutorial.com/ 34
// simulated async function
var promise = $timeout(function() {
if(Math.round(Math.random())) {
return 'data received!'
} else {
return $q.reject('oh no an error! try again')
}
}, 2000);
return promise;
}
}
angular.module('app', [])
.factory('getMyData', getMyData)
.run(function(getData) {
var promise = getData()
.then(function(string) {
console.log(string)
}, function(error) {
console.error(error)
})
.finally(function() {
console.log('Finished at:', new Date())
})
})
A deferred object is simply an object that exposes a promise as well as the associated methods
for resolving that promise. It is constructed using the $q.deferred() function and exposes three
main methods: resolve(), reject(), and notify().
Properties
The associated promise object is accessed via the promise property. promise – {Promise} –
promise object associated with this deferred.
A new promise instance is created when a deferred instance is created and can be retrieved by
calling deferred.promise.
https://riptutorial.com/ 35
The purpose of the promise object is to allow for interested parties to get access to the result of the
deferred task when it completes.
Promise Methods -
One of the most powerful features of promises is the ability to chain them together. This allows the
data to flow through the chain and be manipulated and mutated at each step. This is demonstrated
with the following example:
Example 1:
return promise;
}
https://riptutorial.com/ 36
// 0
console.log(num);
return 'And we are done!';
})
.then(function (text) {
// "And we are done!"
console.log(text);
});
If all you need is to wrap the value into a promise, you don't need to use the long syntax like here:
//OVERLY VERBOSE
var defer;
defer = $q.defer();
defer.resolve(['one', 'two']);
return defer.promise;
//BETTER
return $q.when(['one', 'two']);
$http(config).then(function(res) {
myDeferred.resolve(res);
}, function(error) {
myDeferred.reject(error);
https://riptutorial.com/ 37
});
return myDeferred.promise;
There is no need to manufacture a promise with $q.defer as the $http service already returns a
promise.
//INSTEAD
return $http(config);
https://riptutorial.com/ 38
Chapter 7: AngularJS bindings options (`=`,
`@`, `&` etc.)
Remarks
Use this plunker to play with examples.
Examples
@ one-way binding, attribute binding.
Child scope gets his own value, if it updates the value, parent scope has his own old value (child
scope can't modify the parens scope value). When parent scope value is changed, child scope
value will be changed as well. All interpolations appears every time on digest call, not only on
directive creation.
= two-way binding.
Passing in a value by reference, you want to share the value between both scopes and manipulate
them from both scopes. You should not use {{...}} for interpolation.
https://riptutorial.com/ 39
Passing function by reference is a bad idea: to allow scope to change the definition of a function,
and two unnecessary watcher will be created, you need to minimize watchers count.
Pass a method into a directive. It provides a way to execute an expression in the context of the
parent scope. Method will be executed in the scope of the parent, you may pass some parameters
from the child scope there. You should not use {{...}} for interpolation. When you use & in a
directive, it generates a function that returns the value of the expression evaluated against the
parent scope (not the same as = where you just pass a reference).
angular.component("SampleComponent", {
bindings: {
title: '@',
movies: '<',
reservation: "=",
processReservation: "&"
}
});
@ indicates that we need a very basic binding, from the parent scope to the children scope,
without any watcher, in any way. Every update in the parent scope would stay in the parent scope,
and any update on the child scope would not be communicated to the parent scope.
< indicates a one way binding. Updates in the parent scope would be propagated to the children
scope, but any update in the children scope would not be applied to the parent scope.
= is already known as a two-way binding. Every update on the parent scope would be applied on
the children ones, and every child update would be applied to the parent scope.
& is now used for an output binding. According to the component documentation, it should be
used to reference the parent scope method. Instead of manipulating the children scope, just call
the parent method with the updated data!
https://riptutorial.com/ 40
Bind optional attribute
bindings: {
mandatory: '='
optional: '=?',
foo: '=?bar'
}
Optional attributes should be marked with question mark: =? or =?bar. It is protection for
($compile:nonassign) exception.
https://riptutorial.com/ 41
Chapter 8: AngularJS gotchas and traps
Examples
Two-way data binding stops working
1. Angular's data binding relies on JavaScript’s prototypal inheritance, thus it's subject to
variable shadowing.
2. A child scope normally prototypically inherits from its parent scope. One exception to this rule is a
directive which has an isolated scope as it doesn't prototypically inherit.
3. There are some directives which create a new child scope: ng-repeat, ng-switch, ng-view, ng-
if, ng-controller, ng-include, etc.
This means that when you try to two-way bind some data to a primitive which is inside of a child
scope (or vice-versa), things may not work as expected. Here's an example of how easily is to
"break" AngularJS.
1. Have a "." inside your HTML template whenever you bind some data
2. Use controllerAs syntax as it promotes the use of binding to a "dotted" object
3. $parent can be used to access parent scope variables rather than child scope. like inside ng-
if we can use ng-model="$parent.foo"..
An alternative for the above is to bind ngModel to a getter/setter function that will update the cached
version of the model when called with arguments, or return it when called without arguments. In
order to use a getter/setter function, you need to add ng-model-options="{ getterSetter: true }" to
the element with the ngModal attribute, and to call the getter function if you want to display its value
in expression (Working example).
Example
View:
Controller:
https://riptutorial.com/ 42
angular.module('myApp', []).controller('MainCtrl', ['$scope', function($scope) {
$scope.truthyValue = true;
var _foo = 'hello'; // this will be used to cache/represent the value of the 'foo' model
$scope.foo = function(val) {
// the function return the the internal '_foo' varibale when called with zero
arguments,
// and update the internal `_foo` when called with an argument
return arguments.length ? (_foo = val) : _foo;
};
}]);
Best Practice: It's best to keep getters fast because Angular is likely to call them more frequently
than other parts of your code (reference).
1. You specify the base URL for the application with a <base href=""> in the head of your
index.html.
2. It is important that the base tag comes before any tags with url requests. Otherwise, this
might result in this error - "Resource interpreted as stylesheet but transferred with MIME type
text/html". For example:
<head>
<meta charset="utf-8">
<title>Job Seeker</title>
<base href="/">
3. If you do no want to specify a base tag, configure $locationProvider to not require a base tag
by passing a definition object with requireBase:false to $locationProvider.html5Mode() like
this:
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
4. In order to support direct loading of HTML5 URLs, you need to enabler server-side URL
rewriting. From AngularJS / Developer Guide / Using $location
Using this mode requires URL rewriting on server side, basically you have to
rewrite all your links to entry point of your application (e.g. index.html). Requiring
a <base> tag is also important for this case, as it allows Angular to differentiate
https://riptutorial.com/ 43
between the part of the url that is the application base and the path that should
be handled by the application.
An excellent resource for request rewriting examples for various HTTP server
implementations can be found in the ui-router FAQ - How to: Configure your server to work
with html5Mode. For example, Apache
RewriteEngine on
nginx
server {
server_name my-app;
root /path/to/app;
location / {
try_files $uri $uri/ /index.html;
}
}
Express
Below is the list of some mistakes that developers often make during the use of AngularJS
functionalities, some learned lessons and solutions to them.
It's legal, but must be avoided. Controllers are the places where you define your dependencies,
https://riptutorial.com/ 44
bind your data to the view and make further business logic. You can technically manipulate the
DOM in a controller, but whenever you need same or similar manipulation in another part of your
app, another controller will be needed. So the best practice of this approach is creating a directive
that includes all manipulations and use the directive throughout your app. Hence, the controller
leaves the view intact and does it's job. In a directive, linking function is the best place to
manipulate the DOM. It has full access to the scope and element, so using a directive, you can
also take the advantage of reusability.
You can access DOM elements in linking function through several ways, such as the element
parameter, angular.element() method, or pure Javascript.
AngularJS is famous with its two-way data binding. However you may encounter sometimes that
your data is only one-way bound inside directives. Stop there, AngularJS is not wrong but probably
you. Directives are a little dangerous places since child scopes and isolated scopes are involved.
Assume you have the following directive with one transclusion
<my-dir>
<my-transclusion>
</my-transclusion>
</my-dir>
And inside my-transclusion, you have some elements which are bound to the data in the outer
scope.
<my-dir>
<my-transclusion>
<input ng-model="name">
</my-transclusion>
</my-dir>
The above code will not work correctly. Here, transclusion creates a child scope and you can get
the name variable, right, but whatever change you make to this variable will stay there. So, you
can truly acces this variable as $parent.name. However, this use might not be the best practice. A
better approach would be wrapping the variables inside an object. For example, in the controller
you can create:
$scope.data = {
name: 'someName'
}
Then in the transclusion, you can access this variable via 'data' object and see that two-way
binding works perfectly!
https://riptutorial.com/ 45
<input ng-model="data.name">
Not only in transclusions, but throughout the app, it's a good idea to use the dotted notation.
It is actually legal to use two directives together within the same element, as long as you obey by
the rule: two isolated scopes cannot exist on the same element. Generally speaking, when
creating a new custom directive, you allocate an isolated scope for easy parameter passing.
Assuming that the directives myDirA and myDirB have isoleted scopes and myDirC has not,
following element will be valid:
Therefore, directives must be used wisely, taking the scopes into consideration.
4. Misuse of $emit
$emit, $broadcast and $on, these work in a sender-receiver principle. In others words, they are a
means of communication between controllers. For example, the following line emits the
'someEvent' from controller A, to be catched by the concerned controller B.
$scope.$emit('someEvent', args);
$scope.$on('someEvent', function(){});
So far everything seems perfect. But remember that, if the controller B is not invoked yet, the
event will not be caught, which means both emitter and receiver controllers have to be invoked to
get this working. So again, if you are not sure that you definitely have to use $emit, building a
service seems a better way.
5. Misuse of $scope.$watch
$scope.$watch is used for watching a variable change. Whenever a variable has changed, this
method is invoked. However, one common mistake done is changing the variable inside
$scope.$watch. This will cause inconsistency and infinite $digest loop at some point.
$scope.$watch('myCtrl.myVariable', function(newVal) {
this.myVariable++;
});
So in the above function, make sure you have no operations on myVariable and newVal.
https://riptutorial.com/ 46
6. Binding methods to views
This is one of the deadlisest sins. AngularJS has two-way binding, and whenever something
changes, the views are updated many many times. So, if you bind a method to an attribute of a
view, that method might potentially be called a hundred times, which also drives you crazy during
debugging. However, there are only some attributes that are built for method binding, such as ng-
click, ng-blur, ng-on-change, etc, that expect methods as paremeter. For instance, assume you
have the following view in your markup:
Here you check the disabled status of the view via the method isDisabled. In the controller myCtrl,
you have:
vm.isDisabled = function(){
if(someCondition)
return true;
else
return false;
}
In theory, it may seem correct but technically this will cause an overload, since the method will run
countless times. In order to resolve this, you should bind a variable. In your controller, the
following variable must exist:
vm.isDisabled
You can initiate this variable again in the activation of the controller
if(someCondition)
vm.isDisabled = true
else
vm.isDisabled = false
If the condition is not stable, you may bind this to another event. Then you should bind this
variable to the view:
Now, all the attributes of the view have what they expect and the methods will run only whenever
needed.
AngularJS provides great convenience with some of its functionalities, not only simplifying your
code but also making it more efficient. Some of these features are listed below:
1. angular.forEach for the loops (Caution, you can't "break;" it, you can only prevent getting
into the body, so consider performance here.)
https://riptutorial.com/ 47
2. angular.element for DOM selectors
3. angular.copy: Use this when you should not modify the main object
4. Form validations are already awesome. Use dirty, pristine, touched, valid, required and so
on.
5. Besides Chrome debugger, use remote debugging for mobile development too.
6. And make sure you use Batarang. It's a free Chrome extension where you can easily
inspect scopes
.
https://riptutorial.com/ 48
Chapter 9: angularjs with data filter,
pagination etc
Introduction
Provider example and query about display data with filter, pagination etc in Angularjs.
Examples
Angularjs display data with filter, pagination
$scope.pageSize = 5;
$scope.dishes = [
'noodles',
'sausage',
'beans on toast',
'cheeseburger',
'battered mars bar',
'crisp butty',
'yorkshire pudding',
'wiener schnitzel',
'sauerkraut mit ei',
'salad',
'onion soup',
'bak choi',
'avacado maki'
];
https://riptutorial.com/ 49
Chapter 10: Built-in directives
Examples
Angular expressions - Text vs. Number
This example demonstrates how Angular expressions are evaluated when using type="text" and
type="number" for the input element. Consider the following controller and view:
Controller
app.controller('ctrl', function($scope) {
$scope.textInput = {
value: '5'
};
$scope.numberInput = {
value: 5
};
});
View
• When using + in an expression bound to text input, the operator will concatenate the strings
(first example), displaying 55 on the screen*.
• When using + in an expression bound to number input, the operator return the sum of the
numbers (second example), displaying 10 on the screen*.
*- That is until the user changes the value in the input field, afterward the display will change
accordingly.
Working Example
ngRepeat
ng-repeat is a built in directive in Angular which lets you iterate an array or an object and gives you
the ability to repeat an element once for each item in the collection.
ng-repeat an array
<ul>
https://riptutorial.com/ 50
<li ng-repeat="item in itemCollection">
{{item.Name}}
</li>
</ul>
Where:
item = individual item in the collection
itemCollection = The array you are iterating
ng-repeat an object
<ul>
<li ng-repeat="(key, value) in myObject">
{{key}} : {{value}}
</li>
</ul>
Where:
key = the property name
value = the value of the property
myObject = the object you are iterating
Where:
searchText = the text that the user wants to filter the list by
stringArray = an array of strings, e.g. ['string', 'array']
You can also display or reference the filtered items elsewhere by assigning the filter output an
alias with as aliasName, like so:
https://riptutorial.com/ 51
ng-repeat-start and ng-repeat-end
To repeat multiple DOM elements by defining a start and an end point you can use the ng-repeat-
start and ng-repeat-end directives.
<ul>
<li ng-repeat-start="item in [{a: 1, b: 2}, {a: 3, b:4}]">
{{item.a}}
</li>
<li ng-repeat-end>
{{item.b}}
</li>
</ul>
Output:
• 1
• 2
• 3
• 4
Variables
$middle Boolean Evaluates to true if the element is between the $first and $last
Performance considerations
Rendering ngRepeat can become slow, especially when using large collections.
If the objects in the collection have an identifier property, you should always track by the identifier
instead of the whole object, which is the default functionality. If no identifier is present, you can
always use the built-in $index.
https://riptutorial.com/ 52
<div ng-repeat="item in itemCollection track by item.id">
<div ng-repeat="item in itemCollection track by $index">
Scope of ngRepeat
ngRepeatwill always create an isolated child scope so care must be taken if the parent scope
needs to be accessed inside the repeat.
Here is a simple example showing how you can set a value in your parent scope from a click event
inside of ngRepeat.
$scope.val = 0;
this.val = 0;
$scope.itemCollection = [{
id: 0,
value: 4.99,
label: 'Football'
},
{
id: 1,
value: 6.99,
label: 'Baseball'
},
{
id: 2,
value: 9.99,
label: 'Basketball'
}];
If there was only val = item.value at ng-click it won't update the val in the parent scope because
of the isolated scope. That's why the parent scope is accessed with $parent reference or with the
controllerAs syntax (e.g. ng-controller="mainController as ctrl").
Nested ng-repeat
https://riptutorial.com/ 53
$scope.test = [
['a', 'b', 'c'],
['d', 'e', 'f']
];
});
Here to access the index of parent ng-repeat inside child ng-repeat, you can use $parent.$index.
The ng-show directive shows or hides the HTML element based on if the expression passed to it is
true or false. If the value of the expression is falsy then it will hide. If it is truthy then it will show.
The ng-hide directive is similar. However, if the value is falsy it will show the HTML element. When
the expression is truthy it will hide it.
Controller:
angular.module('app')
.controller('ExampleController', ExampleController);
function ExampleController() {
var vm = this;
View
<p>Enter Password</p>
<input ng-model="main.username" type="text">
<hr>
https://riptutorial.com/ 54
</div>
</section>
ngOptions
ngOptions is a directive that simplifies the creation of a html dropdown box for the selection of an
item from an array that will be stored in a model. The ngOptions attribute is used to dynamically
generate a list of <option> elements for the <select> element using the array or object obtained by
evaluating the ngOptions comprehension expression.
With ng-options the markup can be reduced to just a select tag and the directive will create the
same select:
<select ng-model="selectedFruitNgOptions"
ng-options="curFruit as curFruit.label for curFruit in fruit">
</select>
There is anther way of creating select options using ng-repeat, but it is not recommended to use
ng-repeat as it is mostly used for general purpose like, the forEach just to loop. Whereas ng-options
is specifically for creating select tag options.
<select ng-model="selectedFruit">
<option ng-repeat="curFruit in fruit" value="{{curFruit}}">
{{curFruit.label}}
</option>
</select>
FULL EXAMPLE
Lets see the above example in detail also with some variations in it.
$scope.fruit = [
{ label: "Apples", value: 4, id: 2 },
{ label: "Oranges", value: 2, id: 1 },
{ label: "Limes", value: 4, id: 4 },
{ label: "Lemons", value: 5, id: 3 }
];
https://riptutorial.com/ 55
<option value="{ label: "Apples", value: 4, id: 2 }"> Apples </option>
Effects:
f.label will be the label of the <option> and the value will contain the entire object.
FULL EXAMPLE
Effects:
f.value (4) will be the value in this case while the label is still the same.
FULL EXAMPLE
Effects:
Options will be grouped based on there value. Options with same value will fall under one category
FULL EXAMPLE
<option disabled="" value="{ label: "Apples", value: 4, id: 2 }"> Apples </option>
Effects:
"Apples" and "Limes" will be disabled (unable to select) because of the condition disable when
f.value==4. All options with value=4 shall be disabled
https://riptutorial.com/ 56
FULL EXAMPLE
<!-- label group by group for value in array track by trackexpr -->
<select ng-options="f.value as f.label group by f.value for f in fruit track by f.id" ng-
model="selectedFruit"></select>
Effects:
There is not visual change when using trackBy, but Angular will detect changes by the id instead
of by reference which is most always a better solution.
FULL EXAMPLE
<option disabled="" value="{ label: "Apples", value: 4, id: 2 }"> Apples </option>
Effects:
orderByis a AngularJS standard filter which arranges options in ascending order(by default) so
"Oranges" in this will appear 1st since its id = 1.
FULL EXAMPLE
ngModel
With ng-model you can bind a variable to any type of input field. You can display the variable using
double curly braces, eg {{myAge}}.
As you type in the input field or change it in any way you will see the value in the paragraph
update instantly.
The ng-model variable, in this instance, will be available in your controller as $scope.myName. If you
are using the controllerAs syntax:
https://riptutorial.com/ 57
<div ng-controller="myCtrl as mc">
<input type="text" ng-model="mc.myName">
<p>{{mc.myName}}</p>
</div>
You will need to refer to the controller's scope by pre-pending the controller's alias defined in the
ng-controller attribute to the ng-model variable. This way you won't need to inject $scope into your
controller to reference your ng-model variable, the variable will be available as this.myName inside
your controller's function.
ngClass
Let's assume that you need to show the status of a user and you have several possible CSS
classes that could be used. Angular makes it very easy to choose from a list of several possible
classes which allow you to specify an object list that include conditionals. Angular is able to use
the correct class based on the truthiness of the conditionals.
Your object should contain key/value pairs. The key is a class name that will be applied when the
value (conditional) evaluates to true.
<style>
.active { background-color: green; color: white; }
.inactive { background-color: gray; color: white; }
.adminUser { font-weight: bold; color: yellow; }
.regularUser { color: white; }
</style>
<span ng-class="{
active: user.active,
inactive: !user.active,
adminUser: user.level === 1,
regularUser: user.level === 2
}">John Smith</span>
Angular will check the $scope.user object to see the active status and the level number.
Depending on the values in those variables, Angular will apply the matching style to the <span>.
ngIf
ng-if is a directive similar to ng-show but inserts or removes the element from the DOM instead of
simply hiding it. Angular 1.1.5 introduced ng-If directive. You can Use ng-if directive above 1.1.5
versions. This is useful because Angular will not process digests for elements inside a removed
ng-if reducing the workload of Angular especially for complex data bindings.
Unlike ng-show, the ng-if directive creates a child scope which uses prototypal inheritance. This
means that setting a primitive value on the child scope will not apply to the parent. To set a
primitive on the parent scope the $parent property on the child scope will have to be used.
JavaScript
https://riptutorial.com/ 58
angular.module('MyApp', []);
View
<div ng-controller="myController">
<div ng-if="currentUser">
Hello, {{currentUser}}
</div>
<div ng-if="!currentUser">
<a href="/login">Log In</a>
<a href="/register">Register</a>
</div>
</div>
Working Example
Function Promise
The ngIf directive accepts functions as well, which logically require to return true or false.
<div ng-if="myFunction()">
<span>Span text</span>
</div>
https://riptutorial.com/ 59
The span text will only appear if the function returns true.
$scope.myFunction = function() {
var result = false;
// Code to determine the boolean value of result
return result;
};
The ng-mouseenter and ng-mouseleave directives are useful to run events and apply CSS styling
when you hover into or out of your DOM elements.
The ng-mouseenter directive runs an expression one a mouse enter event (when the user enters his
mouse pointer over the DOM element this directive resides in)
HTML
At the above example, when the user points his mouse over the div, applyStyle turns to true,
which in turn applies the .active CSS class at the ng-class.
The ng-mouseleave directive runs an expression one a mouse exit event (when the user takes his
mouse cursor away from the DOM element this directive resides in)
HTML
Reusing the first example, now when the user takes him mouse pointer away from the div, the
.active class is removed.
ngDisabled
This directive is useful to limit input events based on certain existing conditions.
The ng-disabled directive accepts and expression that should evaluate to either a truthy or a falsy
values.
HTML
https://riptutorial.com/ 60
vm.name.length===0 is evaluated to true if the input's length is 0, which is turn disables the button,
disallowing the user to fire the click event of ng-click
ngDblclick
The ng-dblclick directive is useful when you want to bind a double-click event into your DOM
elements.
HTML
In the above example, the value held at the input will be incremented when the button is double
clicked.
ng-change Evaluates specified expression when the user changes the input.
ng-cloak Prevents displaying the content until AngularJS has taken control.
https://riptutorial.com/ 61
ng-include Used to fetch, compile and include an external HTML fragment to your page.
ng-repeat Used to loop through each item in a collection to create a new template.
ng-classeven Works in conjunction with ngRepeat and take effect only on odd (even) rows.
ng-classodd Works in conjunction with ngRepeat and take effect only on odd (even) rows.
ng-open Used to set the open attribute on the element, if the expression inside ngOpen is truthy.
ngClick
https://riptutorial.com/ 62
The ng-click directive attaches a click event to a DOM element.
The ng-click directive allows you to specify custom behavior when an element of DOM is clicked.
It is useful when you want to attach click events on buttons and handle them at your controller.
This directive accepts an expression with the events object available as $event
HTML
Controller
.controller("ctrl", function($scope) {
$scope.onClick = function(evt) {
console.debug("Hello click event: %o ",evt);
}
})
HTML
HTML
Controller
...
$scope.count = function(){
$scope.count = $scope.count + 1;
}
...
When the button is clicked, an invocation of the onClick function will print "Hello click event"
followed by the event object.
ngRequired
https://riptutorial.com/ 63
The ng-required adds or removes the required validation attribute on an element, which in turn will
enable and disable the require validation key for the input.
It is used to optionally define if an input element is required to have a non-empty value. The
directive is helpful when designing validation on complex HTML forms.
HTML
ng-model-options
ng-model-options allows to change the default behavior of ng-model, this directive allows to register
events that will fire when the ng-model is updated and to attach a debounce effect.
This directive accepts an expression that will evaluate to a definition object or a reference to a
scope value.
Example:
The above example will attach a debounce effect of 500 milliseconds on myValue, which will cause
the model to update 500 ms after the user finished typing over the input (that is, when the myValue
finished updating).
3. allowInvalid: a boolean flag allowing for an invalid value to the model, circumventing default
form validation, by default these values would be treated as undefined.
Example:
https://riptutorial.com/ 64
5. timezone: defines the timezone for the model if the input is of the date or time. types
ngCloak
The ngCloak directive is used to prevent the Angular html template from being briefly
displayed by the browser in its raw (uncompiled) form while your application is loading.
- View source
HTML
<div ng-cloak>
<h1>Hello {{ name }}</h1>
</div>
ngCloak can be applied to the body element, but the preferred usage is to apply multiple ngCloak
directives to small portions of the page to permit progressive rendering of the browser view.
ngInclude
ng-include allows you to delegate the control of one part of the page to a specific controller. You
may want to do this because the complexity of that component is becoming such that you want to
encapsulate all the logic in a dedicated controller.
An example is:
<div ng-include
src="'/gridview'"
ng-controller='gridController as gc'>
</div>
Note that the /gridview will need to be served by the web server as a distinct and legitimate url.
Also, note that the src-attribute accepts an Angular expression. This could be a variable or a
function call for example or, like in this example, a string constant. In this case you need to make
sure to wrap the source URL in single quotes, so it will be evaluated as a string constant. This
is a common source of confusion.
Within the /gridview html, you can refer to the gridController as if it were wrapped around the
page, eg:
<div class="row">
<button type="button" class="btn btn-default" ng-click="gc.doSomething()"></button>
</div>
ngSrc
https://riptutorial.com/ 65
Using Angular markup like {{hash}} in a src attribute doesn't work right. The browser will fetch from
the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. ng-src
directive overrides the original src attribute for the image tag element and solves the problem
ngPattern
The ng-pattern directive accepts an expression that evaluates to a regular expression pattern and
uses that pattern to validate a textual input.
Example:
Lets say we want an <input> element to become valid when it's value (ng-model) is a valid IP
address.
Template:
Controller:
$scope.ipRegex = /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-
9]|[01]?[0-9][0-9]?)\b/;
ngValue
Mostly used under ng-repeat ngValue is useful when dynamically generating lists of radio buttons
using ngRepeat
<script>
angular.module('valueExample', [])
.controller('ExampleController', ['$scope', function($scope) {
$scope.names = ['pizza', 'unicorns', 'robots'];
$scope.my = { favorite: 'unicorns' };
}]);
</script>
<form ng-controller="ExampleController">
<h2>Which is your favorite?</h2>
<label ng-repeat="name in names" for="{{name}}">
{{name}}
<input type="radio"
ng-model="my.favorite"
ng-value="name"
id="{{name}}"
name="favorite">
</label>
<div>You chose {{my.favorite}}</div>
</form>
https://riptutorial.com/ 66
Working plnkr
ngCopy
In the controller
$scope.blockCopy = function(event) {
event.preventDefault();
console.log("Copying won't work");
}
ngPaste
The ngPaste directive specifies custom behavior to run when a user pastes content
ngHref
ngHref is used instead of href attribute, if we have a angular expressions inside href value. The
ngHref directive overrides the original href attribute of an html tag using href attribute such as tag,
tag etc.
The ngHref directive makes sure the link is not broken even if the user clicks the link before
AngularJS has evaluated the code.
Example 1
Example 2 This example dynamically gets the href value from input box and load it as href value.
Example 3
<script>
angular.module('angularDoc', [])
https://riptutorial.com/ 67
.controller('myController', function($scope) {
// Set some scope value.
// Here we set bootstrap version.
$scope.bootstrap_version = '3.3.7';
ngList
The ng-list directive is used to convert a delimited string from a text input to an array of strings or
vice versa.
The ng-list directive uses a default delimiter of ", " (comma space).
You can set the delimiter manually by assigning ng-list a delimeter like this ng-list="; ".
By default ng-list has an attribute ng-trim which is set to true. ng-trim when false, will respect
white space in your delimiter. By default, ng-list does not take white space into account unless
you set ng-trim="false".
Example:
angular.module('test', [])
.controller('ngListExample', ['$scope', function($scope) {
$scope.list = ['angular', 'is', 'cool!'];
}]);
A customer delimiter is set to be ;. And the model of the input box is set to the array that was
created on the scope.
The input box will display with the content: angular; is; cool!
https://riptutorial.com/ 68
Chapter 11: Built-in helper Functions
Examples
angular.equals
The angular.equals function compares and determines if 2 objects or values are equal,
angular.equals performs a deep comparison and returns true if and only if at least 1 of the following
conditions is met.
angular.equals(value1, value2)
This function is helpful when you need to deep compare objects or arrays by their values or results
rather than just references.
Examples
angular.equals(1, 1) // true
angular.equals(1, 2) // false
angular.equals({}, {}) // true, note that {}==={} is false
angular.equals({a: 1}, {a: 1}) // true
angular.equals({a: 1}, {a: 2}) // false
angular.equals(NaN, NaN) // true
angular.isString
The function angular.isString returns true if the object or value given to it is of the type string
angular.isString(value1)
Examples
angular.isString("hello") // true
angular.isString([1, 2]) // false
angular.isString(42) // false
angular.isArray
https://riptutorial.com/ 69
The angular.isArray function returns true if and only if the object or value passed to it is of the type
Array.
angular.isArray(value)
Examples
angular.isArray([]) // true
angular.isArray([2, 3]) // true
angular.isArray({}) // false
angular.isArray(17) // false
It is the equivalent of
Array.isArray(someValue)
angular.merge
The function angular.merge takes all the enumerable properties from the source object to deeply
extend the destination object.
angular.merge(destination, source)
Examples
angular.merge({}, {}) // {}
angular.merge({name: "king roland"}, {password: "12345"})
// {name: "king roland", password: "12345"}
angular.merge({a: 1}, [4, 5, 6]) // {0: 4, 1: 5, 2: 6, a: 1}
angular.merge({a: 1}, {b: {c: {d: 2}}}) // {"a":1,"b":{"c":{"d":2}}}
angular.isDefined(someValue)
Examples
angular.isDefined(42) // true
angular.isDefined([1, 2]) // true
angular.isDefined(undefined) // false
angular.isDefined(null) // true
https://riptutorial.com/ 70
The function angular.isUndefined tests if a value is undefined (it is effectively the opposite of
angular.isDefined)
angular.isUndefined(someValue)
Or just
!angular.isDefined(value)
Examples
angular.isUndefined(42) // false
angular.isUndefined(undefined) // true
angular.isDate
The angular.isDate function returns true if and only if the object passed to it is of the type Date.
angular.isDate(value)
Examples
angular.isNumber
The angular.isNumber function returns true if and only if the object or value passed to it is of the
type Number, this includes +Infinity, -Infinity and NaN
angular.isNumber(value)
"23" == 23 // true
Examples
angular.isNumber("23") // false
angular.isNumber(23) // true
angular.isNumber(NaN) // true
angular.isNumber(Infinity) // true
https://riptutorial.com/ 71
"23" == 23 // true
angular.isFunction
The function angular.isFunction determines and returns true if and only if the value passed to is a
reference to a function.
angular.isFunction(fn)
Examples
angular.toJson
The function angular.toJson will take an object and serialize it into a JSON formatted string.
Unlike the native function JSON.stringify, This function will remove all properties beginning with $$
(as angular usually prefixes internal properties with $$)
angular.toJson(object)
As data needs to be serialized before passing through a network, this function is useful to turn any
data you wish to transmit into JSON.
This function is also useful for debugging as it works similarly to a .toString method would act.
Examples:
angular.fromJson
The function angular.fromJson will deserialize a valid JSON string and return an Object or an Array.
angular.fromJson(string|object)
https://riptutorial.com/ 72
Note that this function is not limited to only strings, it will output a representation of any object
passed to it.
Examples:
angular.fromJson("{\"yogurt\": \"strawberries\"}")
// Object {yogurt: "strawberries"}
angular.fromJson('{jam: "raspberries"}')
// will throw an exception as the string is not a valid JSON
angular.fromJson(this)
// Window {external: Object, chrome: Object, _gaq: Y, angular: Object, ng339: 3…}
angular.fromJson([1, 2])
// [1, 2]
typeof angular.fromJson(new Date())
// "object"
angular.noop
The angular.noop is a function that performs no operations, you pass angular.noop when you need
to provide a function argument that will do nothing.
angular.noop()
A common use for angular.noop can be to provide an empty callback to a function that will
otherwise throw an error when something else than a function is passed to it.
Example:
Additional examples:
angular.noop() // undefined
angular.isFunction(angular.noop) // true
angular.isObject
The angular.isObject return true if and only if the argument passed to it is an object, this function
will also return true for an Array and will return false for null even though typeof null is object .
angular.isObject(value)
https://riptutorial.com/ 73
This function is useful for type checking when you need a defined object to process.
Examples:
angular.isElement
The angular.isElement returns true if the argument passed to it is a DOM Element or a jQuery
wrapped Element.
angular.isElement(elem)
This function is useful to type check if a passed argument is an element before being processed
as such.
Examples:
angular.isElement(document.querySelector("body"))
// true
angular.isElement(document.querySelector("#some_id"))
// false if "some_id" is not using as an id inside the selected DOM
angular.isElement("<div></div>")
// false
angular.copy
The angular.copy function takes an object, array or a value and creates a deep copy of it.
angular.copy()
Example:
Objects:
Arrays:
https://riptutorial.com/ 74
var w = [a, [b, [c, [d]]]];
var q = angular.copy(w);
// q = [a, [b, [c, [d]]]]
At the above example angular.equals(w, q) will evaluate to true because .equals tests equality by
value. however w === q will evaluate to false because strict comparison between objects and
arrays is done by reference.
angular.identity
angular.identity(argument)
This function is useful for functional programming, you can provide this function as a default in
case an expected function was not passed.
Examples:
angular.identity(42) // 42
angular.forEach
The angular.forEach accepts an object and an iterator function. It then runs the iterator function
over each enumerable property/value of the object. This function also works on arrays.
Like the JS version of Array.prototype.forEach The function does not iterate over inherited
properties (prototype properties), however the function will not attempt to process a null or an
undefined value and will just return it.
Examples:
angular.forEach({"a": 12, "b": 34}, (value, key) => console.log("key: " + key + ", value: " +
value))
// key: a, value: 12
// key: b, value: 34
angular.forEach([2, 4, 6, 8, 10], (value, key) => console.log(key))
// will print the array indices: 1, 2, 3, 4, 5
angular.forEach([2, 4, 6, 8, 10], (value, key) => console.log(value))
// will print the array values: 2, 4, 6, 7, 10
angular.forEach(undefined, (value, key) => console.log("key: " + key + ", value: " + value))
// undefined
https://riptutorial.com/ 75
Read Built-in helper Functions online: https://riptutorial.com/angularjs/topic/3032/built-in-helper-
functions
https://riptutorial.com/ 76
Chapter 12: Components
Parameters
Parameter Details
For using two-way data binding. This means that if you update
= that variable in your component scope, the change will be
reflected on the parent scope.
@ String parameters.
- -
Called after this controller’s element and its children have been
$postLink() linked. This hook can be considered analogous to the
ngAfterViewInit and ngAfterContentInit hooks in Angular 2.
https://riptutorial.com/ 77
Remarks
Component is a special kind of directive that uses a simpler configuration which is suitable for a
component-based application structure. Components were introduced in Angular 1.5, the
examples in this section will not work with older AngularJS versions.
Examples
Basic Components and LifeCycle Hooks
What’s a component?
• A component is basically a directive that uses a simpler configuration and that is suitable for
a component-based architecture, which is what Angular 2 is all about. Think of a component
as a widget: A piece of HTML code that you can reuse in several different places in your web
application.
Component
angular.module('myApp', [])
.component('helloWorld', {
template: '<span>Hello World!</span>'
});
Markup
<div ng-app="myApp">
<hello-world> </hello-world>
</div>
Live Demo
angular.module("myApp", [])
.component("helloWorld",{
template: '<span>Hello {{$ctrl.name}}!</span>',
bindings: { name: '@' }
});
https://riptutorial.com/ 78
Markup
<div ng-app="myApp">
<hello-world name="'John'" > </hello-world>
</div>
Live Demo
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
controller: function(){
this.myName = 'Alain';
}
});
Markup
<div ng-app="myApp">
<hello-world name="John"> </hello-world>
</div>
CodePen Demo
Parameters passed to the component are available in the controller's scope just before its $onInit
function gets called by Angular. Consider this example:
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
controller: function(){
this.$onInit = function() {
this.myName = "Mac" + this.name;
}
}
});
In the template from above, this would render "Hello John, I'm MacJohn!".
Note that $ctrl is the Angular default value for controllerAs if one is not specified.
Live Demo
https://riptutorial.com/ 79
Using “require” as an Object
In some instances you may need to access data from a parent component inside your component.
This can be achieved by specifying that our component requires that parent component, the
require will give us reference to the required component controller, which can then be used in our
controller as shown in the example below:
Notice that required controllers are guaranteed to be ready only after the $onInit hook.
angular.module("myApp", [])
.component("helloWorld",{
template: "Hello {{$ctrl.name}}, I'm {{$ctrl.myName}}!",
bindings: { name: '@' },
require: {
parent: '^parentComponent'
},
controller: function () {
// here this.parent might not be initiated yet
this.$onInit = function() {
// after $onInit, use this.parent to access required controller
this.parent.foo();
}
}
});
Keep in mind, though, that this creates a tight coupling between the child and the parent.
Components In angular JS
The components in angularJS can be visualised as a custom directive (< html > this in an HTML
directive, and something like this will be a custom directive < ANYTHING >). A component
contains a view and a controller. Controller contains the business logic which is binded with an
view , which the user sees. The component differs from a angular directive because it contains
less configuration. An angular component can be defined like this.
angular.module("myApp",[]).component("customer", {})
Components are defined on the angular modules. They contains two arguments, One is the name
of the component and second one is a object which contains key value pair, which defines which
view and which controller it is going to use like this .
angular.module("myApp",[]).component("customer", {
templateUrl : "customer.html", // your view here
controller: customerController, //your controller here
controllerAs: "cust" //alternate name for your controller
})
"myApp" is the name of the app we are building and customer is the name of our component. Now
https://riptutorial.com/ 80
for calling it in main html file we will just put it like this
<customer></customer>
Now this directive will be replaced by the view you have specified and the business logic you have
written in your controller.
NOTE : Remember component take a object as second argument while directive take a factory
function as argument.
https://riptutorial.com/ 81
Chapter 13: Constants
Remarks
UPPERCASE your constant: Writing constant in capital is a common best practice used in many
languages. It's also useful to clearly identify the nature of injected elements:
When you see .controller('MyController', function($scope, Profile, EVENT)), you instantly know
that:
Examples
Create your first constant
angular
.module('MyApp', [])
.constant('VERSION', 1.0);
Your constant is now declared and can be injected in a controller, a service, a factory, a provider,
and even in a config method:
angular
.module('MyApp')
.controller('FooterController', function(VERSION) {
this.version = VERSION;
});
Use cases
There is no revolution here, but angular constant can be useful specially when your application
and/or team starts to grow ... or if you simply love writing beautiful code!
• Refactor code. Example with event's names. If you use a lot of events in your application,
you have event's names a little every where. A when a new developper join your team, he
names his events with a different syntax, ... You can easily prevent this by grouping your
event's names in a constant:
angular
.module('MyApp')
https://riptutorial.com/ 82
.constant('EVENTS', {
LOGIN_VALIDATE_FORM: 'login::click-validate',
LOGIN_FORGOT_PASSWORD: 'login::click-forgot',
LOGIN_ERROR: 'login::notify-error',
...
});
angular
.module('MyApp')
.controller('LoginController', function($scope, EVENT) {
$scope.$on(EVENT.LOGIN_VALIDATE_FORM, function() {
...
});
})
... and now, your event's names can take benefits from autocompletion !
angular
.module('MyApp')
.constant('CONFIG', {
BASE_URL: {
APP: 'http://localhost:3000',
API: 'http://localhost:3001'
},
STORAGE: 'S3',
...
});
• Isolate parts. Sometimes, there are some things you are not very proud of ... like hardcoded
value for example. Instead of let them in your main code, you can create an angular constant
angular
.module('MyApp')
.constant('HARDCODED', {
KEY: 'KEY',
RELATION: 'has_many',
VAT: 19.6
});
$scope.settings = {
username: Profile.username,
relation: 'has_many',
vat: 19.6
}
to
$scope.settings = {
https://riptutorial.com/ 83
username: Profile.username,
relation: HARDCODED.RELATION,
vat: HARDCODED.VAT
}
https://riptutorial.com/ 84
Chapter 14: Controllers
Syntax
• <htmlElement ng-controller="controllerName"> ... </htmlElement>
• <script> app.controller('controllerName', controllerFunction); </script>
Examples
Your First Controller
A controller is a basic structure used in Angular to preserve scope and handle certain actions
within a page. Each controller is coupled with an HTML view.
<!DOCTYPE html>
<html ng-app='MyFirstApp'>
Setting the app name with ng-app lets you access the application in an external Javascript file,
which will be covered below.
<script src="js/controllers.js"></script>
We'll need a Javascript file where you define your controllers and their actions/data.
https://riptutorial.com/ 85
<div ng-controller="MyController as mc">
The ng-controller attribute sets the controller for that DOM element and all elements that are
children (recursively) below it.
You can have multiple of the same controller (in this case, MyController) by saying ... as mc, we're
giving this instance of the controller an alias.
The {{ ... }} notation is an Angular expression. In this case, this will set the inner text of that <h1>
element to whatever the value of mc.title is.
Note: Angular employs dual-way data binding, meaning that regardless of how you update the
mc.title value, it will be reflected in both the controller and the page.
Also note that Angular expressions do not have to reference a controller. An Angular expression
can be as simple as {{ 1 + 2 }} or {{ "Hello " + "World" }}.
<button ng-click="mc.clicked()">
ng-click is an Angular directive, in this case binding the click event for the button to trigger the
clicked() function of the MyController instance.
With those things in mind, let's write an implementation of the MyController controller. With the
example above, you would write this code in js/controller.js.
Note that the name we pass here is the same as the name you set in your HTML with the ng-app
directive.
Now that we have the app object, we can use that to create controllers.
app.controller('MyController', function(){
var ctrl = this;
ctrl.clicked = function(){
alert("MyController.clicked()");
};
});
Note: For anything that we want to be a part of the controller instance, we use the this keyword.
https://riptutorial.com/ 86
This is all that is required to build a simple controller.
Creating Controllers
angular
.module('app')
.controller('SampleController', SampleController)
Note: The .$inject will make sure your dependencies doesn't get scrambled after minification.
Also, make sure it's in order with the named function.
There are a couple different ways to protect your controller creation from minification.
The first is called inline array annotation. It looks like the following:
The second parameter of the controller method can accept an array of dependencies. As you can
see I've defined $scope and $http which should correspond to the parameters of the controller
function in which a will be the $scope, and b would be $http. Take note that the last item in the array
should be your controller function.
The second option is using the $inject property. It looks like the following:
This does the same thing as inline array annotation but provides a different styling for those that
prefer one option over the other.
https://riptutorial.com/ 87
Note that in the following example, $scope and $http are reversed. This will cause a problem in the
code.
// Intentional Bug: injected dependencies are reversed which will cause a problem
app.controller('sampleController', ['$scope', '$http',function($http, $scope) {
$http.get('sample.json');
}]);
In Angular $scope is the glue between the Controller and the View that helps with all of our data
binding needs. Controller As is another way of binding controller and view and is mostly
recommended to use. Basically these are the two controller constructs in Angular (i.e $scope and
Controller As).
function CustomerController() {
this.name = {};
this.sendMessage = function() { };
}
controllerAs with vm
function CustomerController() {
/*jshint validthis: true */
var vm = this;
vm.name = {};
vm.sendMessage = function() { };
}
is syntactic sugar over $scope. You can still bind to the View and still access $scope
controllerAs
methods. Using controllerAs, is one of the best practices suggested by the angular core team.
There are many reason for this, few of them are -
• $scope is exposing the members from the controller to the view via an intermediary object. By
setting this.*, we can expose just what we want to expose from the controller to the view. It
also follow the standard JavaScript way of using this.
• using controllerAs syntax, we have more readable code and the parent property can be
accessed using the alias name of the parent controller instead of using the $parent syntax.
• It promotes the use of binding to a "dotted" object in the View (e.g. customer.name instead of
https://riptutorial.com/ 88
name), which is more contextual, easier to read, and avoids any reference issues that may
occur without "dotting".
• Use a capture variable for this when using the controllerAs syntax. Choose a consistent
variable name such as vm, which stands for ViewModel. Because, this keyword is contextual
and when used within a function inside a controller may change its context. Capturing the
context of this avoids encountering this problem.
NOTE: using controllerAs syntax add to current scope reference to current controller, so it
available as field
vm is available as $scope.vm.
To create minification-safe angular controllers, you will change the controller function parameters.
The second argument in the module.controller function should be passed an array, where the last
parameter is the controller function, and every parameter before that is the name of each
injected value.
This is different from the normal paradigm; that takes the controller function with the injected
arguments.
Given:
app.controller('ctrlInject',
[
/* Injected Parameters */
'$Injectable1',
'$Injectable2',
/* Controller Function */
function($injectable1Instance, $injectable2Instance) {
/* Controller Content */
}
]
);
Note: The names of injected parameters are not required to match, but they will be bound in order.
https://riptutorial.com/ 89
var
a=angular.module('myApp');a.controller('ctrlInject',['$Injectable1','$Injectable2',function(b,c){/*
Controller Content */}]);
The minification process will replace every instance of app with a, every instance of
$Injectable1Instance with b, and every instance of $Injectable2Instance with c.
Nested Controllers
Nesting controllers chains the $scope as well. Changing a $scope variable in the nested controller
changes the same $scope variable in the parent controller.
$scope.childFunction = function () {
$scope.parentVariable = "I'm overriding you";
};
});
<body ng-controller="parentController">
What controller am I? {{parentVariable}}
<div ng-controller="childController">
What controller am I? {{childVariable}}
<button ng-click="childFunction()"> Click me to override! </button>
</div>
</body>
Nesting controllers may have it's benefits, but one thing must be kept in mind when doing so.
Calling the ngController directive creates a new instance of the controller - which can often create
confusion and unexpected results.
https://riptutorial.com/ 90
Chapter 15: Controllers with ES6
Examples
Controller
it is very easy to write an angularJS controller with ES6 if your are familiarized with the Object
Oriented Programming :
class exampleContoller{
constructor(service1,service2,...serviceN){
let ctrl=this;
ctrl.service1=service1;
ctrl.service2=service2;
.
.
.
ctrl.service1=service1;
ctrl.controllerName = 'Example Controller';
ctrl.method1(controllerName)
method1(param){
let ctrl=this;
ctrl.service1.serviceFunction();
.
.
ctrl.scopeName=param;
}
.
.
.
methodN(param){
let ctrl=this;
ctrl.service1.serviceFunction();
.
.
}
}
exampleContoller.$inject = ['service1','service2',...,'serviceN'];
export default exampleContoller;
https://riptutorial.com/ 91
Chapter 16: Custom Directives
Introduction
Here you will learn about the Directives feature of AngularJS. Below you will find information on
what Directives are, as well as Basic and Advanced examples of how to use them.
Parameters
Parameter Details
Property to set the scope of the directive. It can be set as false, true or
scope
as an isolate scope: { @, =, <, & }.
scope: falsy Directive uses parent scope. No scope created for directive.
link: function/object The link property can be configured as a function or object. It can
https://riptutorial.com/ 92
Parameter Details
Link function that executes before any child link functions. By default,
child directive link functions execute before parent directive link
pre-link function
functions and the pre-link function enables the parent to link first. One
use case is if the child requires data from the parent.
Link function that executives after child elements are linked to parent. It
is commonly used for attaching event handlers and accessing child
post-link function
directives, but data required by the child directive should not be set
here because the child directive will have already been linked.
Defines how to call the directive from within the DOM. Possible values
(Assuming our directive name is demoDirective): E - Element name (
<demo-directive></demo-directive>), A - Attribute (<div demo-
directive></div>), C - Matching class (<div class="demo-
restrict: string
directive"></div>), M - By comment (<!-- directive: demo-directive -->
). The restrict property can also support multiple options, for example -
restrict: "AC" will restrict the directive to Attribute OR Class. If omitted,
the default value is "EA" (Element or Attribute).
require: Attempt to locate the demoDirective's controller or pass null to the link
'?demoDirective' fn if not found.
require: Locate the demoDirective's controller by searching the element and its
'^demoDirective' parents. Throw an error if not found.
https://riptutorial.com/ 93
Examples
Creating and consuming custom directives
Directives are one of the most powerful features of angularjs. Custom angularjs directives are
used to extend functionality of html by creating new html elements or custom attributes to provide
certain behavior to an html tag.
directive.js
// If you already have the app module created, comment the above line and create a reference
of the app module
var demoApp = angular.module("demoApp");
demoApp.directive('demoDirective', function () {
// The values of scope property decides how the actual scope is created and used inside a
directive. These values can be either “false”, “true” or “{}”. This creates an isolate scope
for the directive.
// '@' binding is for passing strings. These strings support {{}} expressions for
interpolated values.
// '=' binding is for two-way model binding. The model in parent scope is linked to the
model in the directive's isolated scope.
// '&' binding is for passing a method into your directive's scope so that it can be
called within your directive.
// The method is pre-bound to the directive's parent scope, and supports arguments.
scope: {
name: "@", // Always use small casing here even if it's a mix of 2-3 words
},
// compile is called during application initialization. AngularJS calls it once when html
page is loaded.
https://riptutorial.com/ 94
compile: function(element, attributes) {
element.css("border", "1px solid #cccccc");
// linkFunction is linked with each element with scope to get the element specific data.
var linkFunction = function($scope, element, attributes) {
element.html("Name: <b>"+$scope.name +"</b>");
element.css("background-color", "#ff00ff");
};
return linkFunction;
}
};
});
<html>
<head>
<title>Angular JS Directives</title>
</head>
<body>
<script src =
"http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="directive.js"></script>
<div ng-app = "demoApp">
<!-- Notice we are using Spinal Casing here -->
<demo-directive name="World"></demo-directive>
</div>
</body>
</html>
demoApp.directive('demoDirective', function () {
var directiveDefinitionObject = {
multiElement:
priority:
terminal:
scope: {},
bindToController: {},
controller:
controllerAs:
require:
restrict:
templateNamespace:
template:
templateUrl:
transclude:
compile:
link: function(){}
};
return directiveDefinitionObject;
});
1. multiElement - set to true and any DOM nodes between the start and end of the directive
name will be collected and grouped together as directive elements
https://riptutorial.com/ 95
2. priority - allows specification of the order to apply directives when multiple directives are
defined on a single DOM element. Directives with higher numbers are compiled first.
3. terminal - set to true and the current priority will be the last set of directives to execute
4. scope - sets scope of the directive
5. bind to controller - binds scope properties directly to directive controller
6. controller - controller constructor function
7. require - require another directive and inject its controller as the fourth argument to the
linking function
8. controllerAs - name reference to the controller in the directive scope to allow the controller to
be referenced from the directive template.
9. restrict - restrict directive to Element, Attribute, Class, or Comment
10. templateNameSpace - sets document type used by directive template: html, svg, or math. html is
the default
11. template - html markup that defaults to replacing the content of the directive's element, or
wraps the contents of the directive element if transclude is true
12. templateUrl - url provided asynchronously for the template
13. transclude - Extract the contents of the element where the directive appears and make it
available to the directive. The contents are compiled and provided to the directive as a
transclusion function.
14. compile - function to transform the template DOM
15. link - only used if the compile property is not defined. The link function is responsible for
registering DOM listeners as well as updating the DOM. It is executed after the template has
been cloned.
superman-directive.js
angular.module('myApp', [])
.directive('superman', function() {
return {
// restricts how the directive can be used
restrict: 'E',
templateUrl: 'superman-template.html',
controller: function() {
this.message = "I'm superman!"
},
controllerAs: 'supermanCtrl',
// Executed after Angular's initialization. Use commonly
// for adding event handlers and DOM manipulation
link: function(scope, element, attributes) {
element.on('click', function() {
alert('I am superman!')
});
}
}
});
superman-template.html
<h2>{{supermanCtrl.message}}</h2>
https://riptutorial.com/ 96
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="superman-directive.js"><script/>
</head>
<body>
<div ng-app="myApp">
<superman></superman>
</div>
</body>
</html>
You can check out more about directive's restrict and link functions on AngularJS's official
documentation on Directives
AngularJS directives are what controls the rendering of the HTML inside an AngularJS application.
They can be an Html element, attribute, class or a comment. Directives are used to manipulate the
DOM, attaching new behavior to HTML elements, data binding and many more. Some of
examples of directives which angular provides are ng-model, ng-hide, ng-if.
Similarly one can create his own custom directive and make them resuable. For creating Custom
directives Reference. The sense behind creating reusable directives is to make a set of
directives/components written by you just like angularjs provides us using angular.js . These
reusable directives can be particularly very helpful when you have suite of applications/application
which requires a consistent behavior, look and feel. An example of such reusable component can
be a simple toolbar which you may want to use across your application or different applications but
you want them to behave the same or look the same.
Firstly , Make a folder named resuableComponents in your app Folder and make
reusableModuleApp.js
reusableModuleApp.js:
(function(){
//Remember whatever dependencies you have in here should be injected in the app module where
it is intended to be used or it's scripts should be included in your main app
//We will be injecting ng-sanitize
resubaleModuleApp.directive('toolbar', toolbar)
toolbar.$inject=['$sce'];
function toolbar($sce){
https://riptutorial.com/ 97
return{
restrict :'AE',
//Defining below isolate scope actually provides window for the directive to take data
from app that will be using this.
scope : {
value1: '=',
value2: '=',
},
}
template : '<ul> <li><a ng-click="Add()" href="">{{value1}}</a></li> <li><a ng-
click="Edit()" href="#">{{value2}}</a></li> </ul> ',
link : function(scope, element, attrs){
};
};
}
}
});
mainApp.js:
(function(){
var mainApp = angular.module('mainApp', ['reusableModuleApp']); //Inject resuableModuleApp
in your application where you want to use toolbar component
mainApp.controller('mainAppController', function($scope){
$scope.value1 = "Add";
$scope.value2 = "Edit";
});
});
index.html:
<!doctype html>
<html ng-app="mainApp">
<head>
<title> Demo Making a reusable component
<head>
<body ng-controller="mainAppController">
<!-- We need to add the dependent js files on both apps here -->
<script src="js/angular.js"></script>
<script src="js/angular-sanitize.js"></script>
https://riptutorial.com/ 98
<!-- your mainApp.js should be added afterwards --->
<script src="mainApp.js"></script>
</body>
</html>
Directive are reusable components by default. When you make directives in separate angular
module, It actually makes it exportable and reusable across different angularJs applications. New
directives can simply be added inside reusableModuleApp.js and reusableModuleApp can have
it's own controller, services, DDO object inside directive to define the behavior.
Creating a custom directive with isolated scope will separate the scope inside the directive from
the outside scope, in order to prevent our directive from accidentally change the data in the
parent scope and restricting it from reading private data from the parent scope.
To create an isolated scope and still allow our custom directive to communicate with the outside
scope, we can use the scope option that describe how to map the bindings of the directive's inner
scope with the outside scope.
The actual bindings are made with extra attributes attached to the directive. The binding settings
are defined with the scope option and an object with key-value pairs:
• A value, which tells Angular how do bind the directive inner scope to a matching attribute
https://riptutorial.com/ 99
}
}
}
ProgressBar.$inject = [];
angular.module('app').directive('progressBar', ProgressBar);
Example how to use this directive and bind data from the controller's scope to the directive's inner
scope:
Controller:
angular.module('app').controller('myCtrl', function($scope) {
$scope.currentProgressValue = 39;
$scope.maxProgressBarValue = 50;
});
View:
<div ng-controller="myCtrl">
<progress-bar current="currentProgressValue"></progress-bar>
<progress-bar current="currentProgressValue" max-value="maxProgressBarValue"></progress-
bar>
</div>
Directives can be used to build reusable components. Here is an example of a "user box"
component:
userBox.js
Controller.js
myApp.controller('Controller', function($scope) {
$scope.user2 = "Andrew";
$scope.rep2 = 2850;
https://riptutorial.com/ 100
});
myPage.js
<body>
<div ng-controller="Controller">
<user-box username="user" reputation="rep"></user-box>
<user-box username="user2" reputation="rep2"></user-box>
</div>
</body>
</html>
user-box.html
<div>{{username}}</div>
<div>{{reputation}} reputation</div>
John Doe
1250 reputation
Andrew
2850 reputation
Directive decorator
Sometimes you may need additional features from a directive. Instead of rewriting (copy) the
directive, you can modify how the directive behaves.
To do so, provde a .config to your module. The directive is called myDirective, so you have to
config myDirectiveDirective. (this in an angular convention [read about providers] ).
angular.module('myApp').config(function($provide){
$provide.decorator('myDirectiveDirective', function($delegate){
var directive = $delegate[0]; // this is the actual delegated, your directive
directive.templateUrl = 'newTemplate.html'; // you change the directive template
return $delegate;
})
});
https://riptutorial.com/ 101
This example add an onClick event to the directive element when clicked, this happens during
compile phase.
angular.module('myApp').config(function ($provide) {
$provide.decorator('myDirectiveTwoDirective', function ($delegate) {
var directive = $delegate[0];
var link = directive.link; // this is directive link phase
directive.compile = function () { // change the compile of that directive
return function (scope, element, attrs) {
link.apply(this, arguments); // apply this at the link phase
element.on('click', function(){ // when add an onclick that log hello when
the directive is clicked.
console.log('hello!');
});
};
};
return $delegate;
});
});
In this example, directive Adir exposes to directive Bdir it's controller $scope, since Bdir requires
Adir.
angular.module('myApp',[]).directive('Adir', function () {
return {
restrict: 'AE',
controller: ['$scope', function ($scope) {
$scope.logFn = function (val) {
console.log(val);
}
}]
}
})
Make sure to set require: '^Adir' (look at the angular documentation, some versions doesn't require
^ character).
.directive('Bdir', function () {
return {
restrict: 'AE',
require: '^Adir', // Bdir require Adir
link: function (scope, elem, attr, Parent) {
// Parent is Adir but can be an array of required directives.
elem.on('click', function ($event) {
Parent.logFn("Hello!"); // will log "Hello! at parent dir scope
scope.$apply(); // apply to parent scope.
});
}
https://riptutorial.com/ 102
}
}]);
https://riptutorial.com/ 103
Chapter 17: Custom filters
Examples
Simple filter example
Filters format the value of an expression for display to the user. They can be used in view
templates, controllers or services. This example creates a filter (addZ) then uses it in a view. All this
filter does is add a capital 'Z' to the end of the string.
example.js
angular.module('main', [])
.filter('addZ', function() {
return function(value) {
return value + "Z";
}
})
.controller('MyController', ['$scope', function($scope) {
$scope.sample = "hello";
}])
example.html
Inside the view, the filter is applied with the following syntax: { variable | filter}. In this case, the
variable we defined in the controller, sample, is being filtered by the filter we created, addZ.
<div ng-controller="MyController">
<span>{{sample | addZ}}</span>
</div>
Expected output
helloZ
angular
.module('filters', [])
.filter('percentage', function($filter) {
return function (input) {
return $filter('number')(input * 100) + ' %';
};
});
https://riptutorial.com/ 104
Create a filter with parameters
By default, a filter has a single parameter: the variable it is applied on. But you can pass more
parameter to the function:
angular
.module('app', [])
.controller('MyController', function($scope) {
$scope.example = 0.098152;
})
.filter('percentage', function($filter) {
return function (input, decimals) {
return $filter('number')(input * 100, decimals) + ' %';
};
});
... but other parameters are optional, you can still use the default filter:
https://riptutorial.com/ 105
Chapter 18: Custom filters with ES6
Examples
FileSize Filter using ES6
We have here a file Size filter to describe how to add costum filter to an existing module :
let fileSizeFilter=function () {
return function (size) {
if (isNaN(size))
size = 0;
size /= 1024;
size /= 1024;
size /= 1024;
size /= 1024;
return fileSize(size,'To',2);
};
};
export default fileSizeFilter;
<div ng-app="mainApp">
<div>
<input type="text" ng-model="size" />
https://riptutorial.com/ 106
</div>
<div>
<h3>Output:</h3>
<p>{{size| Filesize}}</p>
</div>
</div>
https://riptutorial.com/ 107
Chapter 19: Debugging
Examples
Basic debugging in markup
angular.module('demoApp', [])
.controller('mainController', MainController);
function MainController() {
var vm = this;
vm.items = [{
id: 0,
text: 'first'
},
{
id: 1,
text: 'second'
},
{
id: 2,
text: 'third'
}];
}
Sometimes it can help to see if there is a new scope to fix scoping issues. $scope.$id can be used
in an expression everywhere in your markup to see if there is a new $scope.
In the example you can see that outside of the ul-tag is the same scope ($id=2) and inside the ng-
repeat there are new child scopes for each iteration.
An output of the model in a pre-tag is useful to see the current data of your model. The json filter
creates a nice looking formatted output. The pre-tag is used because inside that tag any new-line
character \n will be correctly displayed.
demo
https://riptutorial.com/ 108
Using ng-inspect chrome extension
When a node is selected from the elements panel, the scope related info is displayed in the ng-
inspect panel.
https://riptutorial.com/ 109
Provides easy access to Services/Factories.
https://riptutorial.com/ 110
Performance of the application can be monitored by counting the no.of scopes,isolateScopes,
watchers and listeners on the application.
Use $count() to get the count of scopes, isolateScopes, watchers and listeners.
https://riptutorial.com/ 111
Note: This extension will work only when the debugInfo is enabled.
In an angular app everything goes around scope, if we could get an elements scope then it is easy
to debug the angular app. How to access the scope of element:
angular.element(myDomElement).scope();
e.g.
angular.element(document.getElementById('yourElementId')).scope() //accessing by ID
https://riptutorial.com/ 112
angular.element('[ng-controller=ctrl]').scope()
Another easy way to access a DOM element from the console (as jm mentioned) is to click on it in
the 'elements' tab, and it automatically gets stored as $0.
angular.element($0).scope();
https://riptutorial.com/ 113
Chapter 20: Decorators
Syntax
• decorator(name, decorator);
Remarks
Decorator is function that allow a service, factory, directive or filter to be modified prior
to its usage. Decorator is used to override or modify the behavior of the service. The
return value of the decorator function may be the original service, or a new service that
replaces, or wraps and delegates to, the original service.
Any decorating must be done in angular application's config phase by injecting $provide and using
it's $provide.decorator function.
The decorator function has a $delegate object injected to provide access to the service
that matches the selector in the decorator. This $delegate will be the service you are
decorating. The return value of the function provided to the decorator will take place of
the service, directive, or filter being decorated.
One should consider using decorator only if any other approach is not appropriate or proves to be
too tedious. If large application is using same service, and one part is changing service behavior,
it's easy to create confusion and/or bugs in the process.
Typical use case would be when you have a 3rd party dependency which you can't upgrade but
need it to work little differently or extend it.
Examples
Decorate service, factory
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myService', function($delegate) {
$delegate.getDate = function() { // override with actual date object
return new Date();
};
return $delegate;
});
})
.service('myService', function() {
this.getDate = function() {
return null; // w/o decoration we'll be returning null
https://riptutorial.com/ 114
};
})
.controller('myController', function(myService) {
var vm = this;
vm.date = myService.getDate();
});
Decorate directive
Directives can be decorated just like services and we can modify or replace any of it's
functionality. Note that directive itself is accessed at position 0 in $delegate array and name
parameter in decorator must include Directive suffix (case sensitive).
So, if directive is called myDate, it can be accessed using myDateDirective using $delegate[0].
Below is simple example where directive shows current time. We'll decorate it to update current
time in one second intervals. Without decoration it will always show same time.
<body>
<my-date></my-date>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('myDateDirective', function($delegate, $interval) {
var directive = $delegate[0]; // access directive
return $delegate;
});
})
.directive('myDate', function() {
return {
restrict: 'E',
template: '<span>Current time is {{ date | date:\'MM:ss\' }}</span>',
link: function(scope) {
scope.date = new Date(); // get current date
}
https://riptutorial.com/ 115
};
});
Decorate filter
When decorating filters, name parameter must include Filter suffix (case sensitive). If filter is
called repeat, decorator parameter is repeatFilter. Below we'll decorate custom filter that repeats
any given string n times so that result is reversed. You can also decorate angular's build-in filters
the same way, although not recommended as it can affect the functionality of the framework.
<body>
<div ng-bind="'i can haz cheeseburger ' | repeat:2"></div>
</body>
angular.module('app', [])
.config(function($provide) {
$provide.decorator('repeatFilter', function($delegate) {
return function reverse(input, count) {
// reverse repeated string
return ($delegate(input, count)).split('').reverse().join('');
};
});
})
.filter('repeat', function() {
return function(input, count) {
// repeat string n times
return (input || '').repeat(count || 1);
};
});
https://riptutorial.com/ 116
Chapter 21: Dependency Injection
Syntax
• myApp.controller('MyController', function($scope) { ... }); // non-minified code
• function MyController(){}
MyController.$inject = ['$scope'];
Remarks
Providers cannot be injected into run blocks.
Make sure to annotate your injections so your code will not break on minification.
Examples
Injections
The simplest example of an injection in an Angular app - injecting $scope to an Angular Controller:
angular.module('myModule', [])
.controller('myController', ['$scope', function($scope) {
$scope.members = ['Alice', 'Bob'];
...
}])
The above illustrates an injection of a $scope into a controller, but it is the same whether you inject
any module into any other. The process is the same.
Angular's system is in charge of resolving dependencies for you. If you create a service for
instance, you can list it like in the example above and it will be available for you.
You can use DI - Dependency Injection - wherever you are defining a component.
Note that in the above example we use what is called "Inline Array Annotation". Meaning, we
explicitly write as strings the names of our dependencies. We do it to prevent the application from
breaking when the code is minified for Production. Code minification changes the names of the
https://riptutorial.com/ 117
variables (but not strings), which breaks the injection. By using strings, Angular knows which
dependencies we want.
Very important - the order of string names must be the same as the parameters in the
function.
There are tools that automate this process and take care of this for you.
Dynamic Injections
There is also an option to dynamically request components. You can do it using the $injector
service:
Note: while this method could be used to prevent the circular dependency issue that might break
your app, it is not considered best practice to bypass the problem by using it. Circular dependency
usually indicates there is a flaw in your application's architecture, and you should address that
instead.
Equivalently, we can use the $inject property annotation to achieve the same as above:
You can load AngularJS services in vanilla JavaScript using AngularJS injector() method. Every
jqLite element retrieved calling angular.element() has a method injector() that can be used to
retrieve the injector.
var service;
var serviceName = 'myService';
In the above example we try to retrieve the jqLite element containing the root of the AngularJS
https://riptutorial.com/ 118
application (ngAppElement). To do that, we use angular.element() method, searching for a DOM
element containing ng-app or data-ng-app attribute or, if it does not exists, we fall back to document
element. We use ngAppElement to retrieve injector instance (with ngAppElement.injector()). The
injector instance is used to check if the service to inject exists (with injector.has()) and then to
load the service (with injector.get()) inside service variable.
https://riptutorial.com/ 119
Chapter 22: digest loop walkthrough
Syntax
• $scope.$watch(watchExpression, callback, [deep compare])
• $scope.$digest()
• $scope.$apply([exp])
Examples
two way data binding
Angular has some magic under its hood. it enables binding DOM to real js variables.
Angular uses a loop, named the "digest loop", which is called after any change of a variable -
calling callbacks which update the DOM.
For example, the ng-model directive attaches a keyup eventListener to this input:
Every time the keyup event fires, the digest loop starts.
At some point, the digest loop iterates over a callback which updates the contents of this span:
<span>{{variable}}</span>
The basic life-cycle of this example, summarizes (very Schematically) how angular works::
Implementing two-way-data-binding, to achieve the result from the previous example, could be
done with two core functions:
https://riptutorial.com/ 120
<input id="input"/>
<span id="span"></span>
Now we could now use these functions to hook up a variable to the DOM (angular comes with
built-in directives which will do this for you):
var realVar;
//this is usually done by ng-model directive
input1.addEventListener('keyup',function(e){
realVar=e.target.value;
$digest()
}, true);
Off-course, the real implementations are more complex, and support parameters such as which
element to bind to, and what variable to use
The previous example is good enough when we need to bind a single html element, to a single
variable.
This ng-repeat binds 5 elements to 5 variables called number, with a different value for each of
them!
The way angular achieves this behavior is using a separate context for each element which needs
https://riptutorial.com/ 121
separate variables. This context is called a scope.
Each scope contains properties, which are the variables bound to the DOM, and the $digest and
$watch functions are implemented as methods of the scope.
The DOM is a tree, and variables need to be used in different levels of the tree:
<div>
<input ng-model="person.name" />
<span ng-repeat="number in [1,2,3,4,5]">{{number}} {{person.name}}</span>
</div>
But as we saw, the context(or scope) of variables inside ng-repeat is different to the context above
it. To solve this - angular implements scopes as a tree.
Each scope has an array of children, and calling its $digest method will run all of its children's
$digest method.
This way - after changing the input - $digest is called for the div's scope, which then runs the
$digest for its 5 children - which will update its content.
function $scope(){
this.$children = [];
this.$watches = [];
}
$scope.prototype.$digest = function(){
this.$watches.forEach(function($w){
var val = $w.val();
if($w.prevVal !== val){
$w.callback(val, $w.prevVal);
$w.prevVal = val;
}
});
this.$children.forEach(function(c){
c.$digest();
});
}
https://riptutorial.com/ 122
Chapter 23: Directives using
ngModelController
Examples
A simple control: rating
0 1 2 3 4 5 x
Clicking on a number selects that rating; and clicking the "x" sets the rating to null.
app.directive('rating', function() {
function RatingController() {
this._ngModel = null;
this.rating = null;
this.options = null;
this.min = typeof this.min === 'number' ? this.min : 1;
this.max = typeof this.max === 'number' ? this.max : 5;
}
RatingController.prototype.setNgModel = function(ngModel) {
this._ngModel = ngModel;
if( ngModel ) {
// KEY POINT 1
ngModel.$render = this._render.bind(this);
}
};
RatingController.prototype._render = function() {
this.rating = this._ngModel.$viewValue != null ? this._ngModel.$viewValue : -
Number.MAX_VALUE;
};
RatingController.prototype._calculateOptions = function() {
if( this.min == null || this.max == null ) {
this.options = [];
}
else {
this.options = new Array(this.max - this.min + 1);
for( var i=0; i < this.options.length; i++ ) {
this.options[i] = this.min + i;
}
}
};
https://riptutorial.com/ 123
RatingController.prototype.setValue = function(val) {
this.rating = val;
// KEY POINT 2
this._ngModel.$setViewValue(val);
};
// KEY POINT 3
Object.defineProperty(RatingController.prototype, 'min', {
get: function() {
return this._min;
},
set: function(val) {
this._min = val;
this._calculateOptions();
}
});
Object.defineProperty(RatingController.prototype, 'max', {
get: function() {
return this._max;
},
set: function(val) {
this._max = val;
this._calculateOptions();
}
});
return {
restrict: 'E',
scope: {
// KEY POINT 3
min: '<?',
max: '<?',
nullifier: '<?'
},
bindToController: true,
controllerAs: 'ctrl',
controller: RatingController,
require: ['rating', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<span ng-repeat="o in ctrl.options" href="#" class="rating-option" ng-
class="{\'rating-option-active\': o <= ctrl.rating}" ng-click="ctrl.setValue(o)">{{ o
}}</span>' +
'<span ng-if="ctrl.nullifier" ng-click="ctrl.setValue(null)" class="rating-
nullifier">✖</span>'
};
});
Key points:
https://riptutorial.com/ 124
Object.defineProperty()) to save a few watches.
Note 1: In order not to overcomplicate the implementation, the rating values are inserted in an
array - the ctrl.options. This is not needed; a more efficient, but also more complex,
implementation could use DOM manipulation to insert/remove ratings when min/max change.
Note 2: With the exception of the '<' scope bindings, this example can be used in Angular < 1.5. If
you are on Angular >= 1.5, it would be a good idea to tranform this to a component and use the
$onInit() lifecycle hook to initialize min and max, instead of doing so in the controller's constructor.
A custom control does not have to limit itself to trivial things like primitives; it can edit more
interesting things. Here we present two types of custom controls, one for editing persons and one
for editing addresses. The address control is used to edit the person's address. An example of
usage would be:
<input-person ng-model="data.thePerson"></input-person>
<input-address ng-model="data.thePerson.address"></input-address>
function Person(data) {
data = data || {};
this.name = data.name;
this.address = data.address ? new Address(data.address) : null;
}
function Address(data) {
data = data || {};
this.street = data.street;
this.number = data.number;
}
app.directive('inputAddress', function() {
InputAddressController.$inject = ['$scope'];
function InputAddressController($scope) {
this.$scope = $scope;
this._ngModel = null;
this.value = null;
this._unwatch = angular.noop;
}
InputAddressController.prototype.setNgModel = function(ngModel) {
this._ngModel = ngModel;
if( ngModel ) {
// KEY POINT 3
https://riptutorial.com/ 125
ngModel.$render = this._render.bind(this);
}
};
InputAddressController.prototype._makeWatch = function() {
// KEY POINT 1
this._unwatch = this.$scope.$watchCollection(
(function() {
return this.value;
}).bind(this),
(function(newval, oldval) {
if( newval !== oldval ) { // skip the initial trigger
this._ngModel.$setViewValue(newval !== null ? new Address(newval) : null);
}
}).bind(this)
);
};
InputAddressController.prototype._render = function() {
// KEY POINT 2
this._unwatch();
this.value = this._ngModel.$viewValue ? new Address(this._ngModel.$viewValue) : null;
this._makeWatch();
};
return {
restrict: 'E',
scope: {},
bindToController: true,
controllerAs: 'ctrl',
controller: InputAddressController,
require: ['inputAddress', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<div>' +
'<label><span>Street:</span><input type="text" ng-model="ctrl.value.street"
/></label>' +
'<label><span>Number:</span><input type="text" ng-model="ctrl.value.number"
/></label>' +
'</div>'
};
});
Key points:
1. We are editing an object; we do not want to change directly the object given to us from our
parent (we want our model to be compatible with the immutability principle). So we create a
shallow watch on the object being edited and update the model with $setViewValue()
whenever a property changes. We pass a copy to our parent.
2. Whenever the model changes from the outside, we copy it and save the copy to our scope.
Immutability principles again, though the internal copy is not immutable, the external could
very well be. Additionally we rebuild the watch (this_unwatch();this._makeWatch();), to avoid
triggering the watcher for changes pushed to us by the model. (We only want the watch to
trigger for changes made in the UI.)
3. Other that the points above, we implement ngModel.$render() and call ngModel.$setViewValue()
https://riptutorial.com/ 126
as we would for a simple control (see the rating example).
The code for the person custom control is almost identical. The template is using the <input-
address>. In a more advanced implementation we could extract the controllers in a reusable
module.
app.directive('inputPerson', function() {
InputPersonController.$inject = ['$scope'];
function InputPersonController($scope) {
this.$scope = $scope;
this._ngModel = null;
this.value = null;
this._unwatch = angular.noop;
}
InputPersonController.prototype.setNgModel = function(ngModel) {
this._ngModel = ngModel;
if( ngModel ) {
ngModel.$render = this._render.bind(this);
}
};
InputPersonController.prototype._makeWatch = function() {
this._unwatch = this.$scope.$watchCollection(
(function() {
return this.value;
}).bind(this),
(function(newval, oldval) {
if( newval !== oldval ) { // skip the initial trigger
this._ngModel.$setViewValue(newval !== null ? new Person(newval) : null);
}
}).bind(this)
);
};
InputPersonController.prototype._render = function() {
this._unwatch();
this.value = this._ngModel.$viewValue ? new Person(this._ngModel.$viewValue) : null;
this._makeWatch();
};
return {
restrict: 'E',
scope: {},
bindToController: true,
controllerAs: 'ctrl',
controller: InputPersonController,
require: ['inputPerson', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<div>' +
'<label><span>Name:</span><input type="text" ng-model="ctrl.value.name"
/></label>' +
'<input-address ng-model="ctrl.value.address"></input-address>' +
'</div>'
};
https://riptutorial.com/ 127
});
Note: Here the objects are typed, i.e. they have proper constructors. This is not obligatory; the
model can be plain JSON objects. In this case just use angular.copy() instead of the constructors.
An added advantage is that the controller becomes identical for the two controls and can easily be
extracted into some common module.
Two versions of the fiddle having extracted the common code of the controllers:
https://jsfiddle.net/agj4cp0e/ and https://jsfiddle.net/ugb6Lw8b/
https://riptutorial.com/ 128
Chapter 24: Distinguishing Service vs
Factory
Examples
Factory VS Service once-and-for-all
By definition:
Debate:
But at the same time, Services can also be written to return an object literal and to run code before
returning. Though that is contra productive as services are designed to act as constructor function.
The constructor syntax of services is more close to class syntax of ES6. So migration will be easy.
Summary
A factory is a special case of a provider when all you need in your provider is a $get() function. It
allows you to write it with less code.
A service is a special case of a factory when you want to return an instance of a new object, with
the same benefit of writing less code.
https://riptutorial.com/ 129
Read Distinguishing Service vs Factory online:
https://riptutorial.com/angularjs/topic/7099/distinguishing-service-vs-factory
https://riptutorial.com/ 130
Chapter 25: Events
Parameters
args data that has been passed along with event execution
Examples
Using angular event system
$scope.$emit
Using $scope.$emit will fire an event name upwards through the scope hierarchy and notify to the
$scope.The event life cycle starts at the scope on which $emit was called.
Working wireframe :
https://riptutorial.com/ 131
$scope.$broadcast
Using $scope.$broadcast will fire an event down the $scope. We can listen of these events using
$scope.$on
Working wireframe :
Syntax :
// firing an event upwards
$scope.$emit('myCustomEvent', 'Data to send');
Instead of $scope you can use $rootScope, in that case your event will be available in all the
controllers regardless of that controllers scope
https://riptutorial.com/ 132
The reason to clean the registered events because even the controller has been destroyed the
handling of registered event are still alive. So the code will run as unexpected for sure.
// listening an event
var listenerEventHandler = $rootScope.$on('myEvent', function(){
//handle code
});
$scope.$on('$destroy', function() {
listenerEventHandler();
});
$emitdispatches an event upwards through the scope hierarchy, while $broadcast dispatches an
event downwards to all child scopes.This has been beautifully explained here.
There can be basically two types of scenario while communicating among controllers:
1. When controllers have Parent-Child relationship. (we can mostly use $scope in such
scenarios)
2. When controllers are not independent to each other and are needed to be informed about
each others activity. (we can use $rootScope in such scenarios)
eg: For any ecommerce website, suppose we have ProductListController(which controls the
product listing page when any product brand is clicked ) and CartController (to manage cart items)
. Now, when we click on Add to Cart button , it has to be informed to CartController as well, so
that it can reflect new cart item count/details in the navigation bar of the website. This can be
achieved using $rootScope.
With $scope.$emit
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
https://riptutorial.com/ 133
app.controller("SecondController", function ($scope) {
$scope.handleClick = function (msg) {
$scope.$emit('eventName', {message: msg});
};
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px ;padding:5px;">
<h1>Parent Controller</h1>
<p>Emit Message : {{message}}</p>
<br />
<div ng-controller="SecondController" style="border:2px;padding:5px;">
<h1>Child Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Emit</button>
</div>
</div>
</body>
</html>
With $scope.$broadcast:
<html>
<head>
<title>Broadcasting</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.4/angular.js"></script>
<script>
var app = angular.module('app', []);
});
</script>
</head>
<body ng-app="app">
<div ng-controller="FirstController" style="border:2px solid ; padding:5px;">
<h1>Parent Controller</h1>
<input ng-model="msg">
<button ng-click="handleClick(msg);">Broadcast</button>
<br /><br />
<div ng-controller="SecondController" style="border:2px solid ;padding:5px;">
<h1>Child Controller</h1>
<p>Broadcast Message : {{message}}</p>
</div>
</div>
</body>
</html>
https://riptutorial.com/ 134
Always deregister $rootScope.$on listeners on the scope $destory event
$rootScope.$on listeners will remain in memory if you navigate to another controller. This will
create a memory leak if the controller falls out of scope.
Don't
angular.module('app').controller('badExampleController', badExample);
Do
angular.module('app').controller('goodExampleController', goodExample);
https://riptutorial.com/ 135
Chapter 26: Filters
Examples
Your First Filter
Filters are a special type of function that can modify how something is printed out to the page, or
can be used to filter an array, or a ng-repeat action. You can create a filter by calling the
app.filter() method, passing it a name and a function. See the examples below for details on
syntax.
For example, let's create a filter that will change a string to be all uppercase (essentially a wrapper
of the .toUpperCase() javascript function):
First, we're creating a filter called "toUppercase", which is just like a controller; app.filter(...).
Then, that filter's function returns the actual filter function. That function takes a single object,
which is the object to be filtered, and should return the filtered version of the object.
Note: In this situation, we're assuming the object being passed into the filter is a string, and
therefore know to always use the filter only on strings. That being said, a further improvement to
the filter could be made that loops through the object (if it's an array) and then makes every
element that is a string uppercase.
Now let's use our new filter in action. Our filter can be used in two ways, either in an angular
template or as a javascript function (as an injected Angular reference).
Javascript
Simply inject the angular $filter object to your controller, then use that to retrieve the filter
function using its name.
https://riptutorial.com/ 136
app.controller("MyController", function($scope, $filter){
this.rawString = "Foo";
this.capsString = $filter("toUppercase")(this.rawString);
});
HTML
For an angular directive, use the pipe (|) symbol followed by the filter name in the directive after
the actual string. For example, let's say we have a controller called MyController that has a string
called rawString as a element of it.
Editor's Note: Angular has a number of built in filters, including "uppercase", and the
"toUppercase" filter is intended only as a demo to easily show off how filters work, but you do not
need to built your own uppercase function.
A typical use case for a filter is to remove values from an array. In this example we pass in an
array and remove any nulls found in it, returning the array.
function removeNulls() {
return function(list) {
for (var i = list.length - 1; i >= 0; i--) {
if (typeof list[i] === 'undefined' ||
list[i] === null) {
list.splice(i, 1);
}
}
return list;
};
}
{{listOfItems | removeNulls}}
or in a controller like
listOfItems = removeNullsFilter(listOfItems);
Another use case for filters is to format a single value. In this example, we pass in a value and we
are returned an appropriate true boolean value.
https://riptutorial.com/ 137
function convertToBooleanValue() {
return function(input) {
if (typeof input !== 'undefined' &&
input !== null &&
(input === true || input === 1 || input === '1' || input
.toString().toLowerCase() === 'true')) {
return true;
}
return false;
};
}
{{isAvailable | convertToBooleanValue}}
Or in a controller like:
This example was done in order to demonstrate how you can perform a deep filter in a child array
without the necessity of a custom filter.
Controller:
(function() {
"use strict";
angular
.module('app', [])
.controller('mainCtrl', mainCtrl);
function mainCtrl() {
var vm = this;
https://riptutorial.com/ 138
"name":"Commercial vehicle"
}
]
},
{
"name":"car3",
"classifications":[
{
"name":"Sport car"
},
{
"name":"Sedans"
}
]
}
];
}
})();
View:
By injecting $filter, any defined filter in your Angular module may be used in controllers, services,
directives or even other filters.
angular.module("app")
.service("users", usersService)
.controller("UsersController", UsersController);
function usersService () {
this.getAll = function () {
return [{
id: 1,
username: "john"
}, {
id: 2,
username: "will"
}, {
id: 3,
username: "jack"
}];
https://riptutorial.com/ 139
};
}
Occasionally you will want to access the result of your filters from outside the ng-repeat, perhaps to
indicate the number of items that have been filtered out. You can do this using as [variablename]
syntax on the ng-repeat.
<ul>
<li ng-repeat="item in vm.listItems | filter:vm.myFilter as filtered">
{{item.name}}
</li>
</ul>
<span>Showing {{filtered.length}} of {{vm.listItems.length}}</span>
https://riptutorial.com/ 140
Chapter 27: Form Validation
Examples
Basic Form Validation
Dealing with traditional form inputs and having to use interrogative jQuery-style processing can be
time-consuming and finicky. Angular allows you to produce professional interactive forms relatively
easily.
The ng-model directive provides two-way binding with input fields and usually the novalidate
attribute is also placed on the form element to prevent the browser from doing native validation.
For Angular to validate inputs, use exactly the same syntax as a regular input element, except for
the addition of the ng-model attribute to specify which variable to bind to on the scope. Email is
shown in the prior example. To validate a number, the syntax would be:
The final steps to basic form validation are connecting to a form submit function on the controller
using ng-submit, rather than allowing the default form submit to occur. This is not mandatory but
it is usually used, as the input variables are already available on the scope and so available to
your submit function. It is also usually good practice to give the form a name. These changes
would result in the following syntax:
This above code is functional but there is other functionality that Angular provides.
The next step is to understand that Angular attaches class attributes using ng-pristine, ng-dirty,
ng-valid and ng-invalid for form processing. Using these classes in your css will allow you to
style valid/invalid and pristine/dirty input fields and so alter the presentation as the user is
entering data into the form.
https://riptutorial.com/ 141
Form and Input States
Angular Forms and Inputs have various states that are useful when validating content
Input States
State Description
All of the above states are boolean properties and can be either true or false.
Here, we are using the ng-show directive to display a message to a user if they've modified a form
but it's invalid.
CSS Classes
Angular also provides some CSS classes for forms and inputs depending on their state
Class Description
https://riptutorial.com/ 142
You can use these classes to add styles to your forms
input.ng-invalid {
background-color: crimson;
}
input.ng-valid {
background-color: green;
}
ngMessages
ngMessages is used to enhanced the style for displaying validation messages in the view.
Traditional approach
Before ngMessages, we normally display the validation messages using Angular pre-defined
directives ng-class.This approach was litter and a repetitive task.
Example
Html :
<form name="ngMessagesDemo">
<input name="firstname" type="text" ng-model="firstname" required>
<div ng-messages="ngMessagesDemo.firstname.$error">
<div ng-message="required">Firstname is required.</div>
</div>
</form>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.16/angular-
messages.min.js"></script>
JS :
In some cases basic validation is not enough. Angular support custom validation adding validator
functions to the $validators object on the ngModelController:
https://riptutorial.com/ 143
angular.module('app', [])
.directive('myValidator', function() {
return {
// element must have ng-model attribute
// or $validators does not work
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$validators.myValidator = function(modelValue, viewValue) {
// validate viewValue with your custom logic
var valid = (viewValue && viewValue.length > 0) || false;
return valid;
};
}
};
The validator is defined as a directive that require ngModel, so to apply the validator just add the
custom directive to the input form control.
<form name="form">
<input type="text"
ng-model="model"
name="model"
my-validator>
<pre ng-bind="'my-validator returned: ' + form.model.$valid"></pre>
</form>
And my-validator doesn't have to be applied on native form control. It can be any elements, as
long as it as ng-model in its attributes. This is useful when you have some custom build ui
component.
Nested Forms
Sometimes it is desirable to nest forms for the purpose of grouping controls and inputs logically on
the page. However, HTML5 forms should not be nested. Angular supplies ng-form instead.
https://riptutorial.com/ 144
<p>Has any field on my form been edited? {{myForm.$dirty}}</p>
<p>Is my nested form valid? {{myForm.myNestedForm.$valid}}</p>
<p>Is myInput1 valid? {{myForm.myNestedForm.myInput1.$valid}}</p>
Each part of the form contributes to the overall form's state. Therefore, if one of the inputs myInput1
has been edited and is $dirty, its containing form will also be $dirty. This cascades to each
containing form, so both myNestedForm and myForm will be $dirty.
Async validators
Asynchronous validators allows you to validate form information against your backend (using
$http).
These kind of validators are needed when you need to access server stored information you can't
have on your client for various reasons, such as the users table and other database information.
To use async validators, you access the ng-model of your input and define callback functions for
the $asyncValidators property.
Example:
The following example checks if a provided name already exists, the backend will return a status
that will reject the promise if the name already exists or if it wasn't provided. If the name doesn't
exist it will return a resolved promise.
Now everytime the ng-model of the input is changed, this function will run and return a promise with
the result.
https://riptutorial.com/ 145
Chapter 28: Grunt tasks
Examples
Run application locally
Usually one of the first things you want to do when developing new web application is to make it
run locally.
Below you'll find complete example achieving just that, using grunt (javascript task runner), npm
(node package manager) and bower (yet another package manager).
Beside your actual application files you'll need to install few 3rd party dependencies using tools
mentioned above. In your project directory, preferably root, you'll need three (3) files.
package.json
We'll be installing grunt itself, matchdep to make our life easier allowing us to filter dependencies
by name, grunt-express used to start express web server via grunt and grunt-open to open
urls/files from a grunt task.
So these packages are all about "infrastructure" and helpers we'll be building our application on.
{
"name": "app",
"version": "1.0.0",
"dependencies": {},
"devDependencies": {
"grunt": "~0.4.1",
"matchdep": "~0.1.2",
"grunt-express": "~1.0.0-beta2",
"grunt-open": "~0.2.1"
https://riptutorial.com/ 146
},
"scripts": {
"postinstall": "bower install"
}
}
bower.json
Bower is (or at least should be) all about front-end and we'll be using it to install angular.
{
"name": "app",
"version": "1.0.0",
"dependencies": {
"angular": "~1.3.x"
},
"devDependencies": {}
}
gruntfile.js
Inside gruntfile.js we'll have the actual "running application locally" magic, which opens our
application in new browser window, running on http://localhost:9000/
'use strict';
// see http://rhumaric.com/2013/07/renewing-the-grunt-livereload-magic/
module.exports = function(grunt) {
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
express: {
all: {
options: {
port: 9000,
hostname: 'localhost',
bases: [__dirname]
}
}
},
open: {
all: {
path: 'http://localhost:<%= express.all.options.port%>'
}
}
});
grunt.registerTask('app', [
'express',
'open',
'express-keepalive'
]);
};
Usage
https://riptutorial.com/ 147
To get your application up & running from scratch, save above files to your project's root directory
(any empty folder will do). Then fire up console/command line and type in the following to install all
required dependencies.
grunt app
Note that yes, you'll be needing your actual application files, too.
For almost-minimal example browse GitHub repository mentioned in beginning of this example.
There structure ain't that different. There's just index.html template, angular code in app.js and few
styles in app.css. Other files are for Git and editor configuration and some generic stuff. Give it a
try!
https://riptutorial.com/ 148
Chapter 29: How data binding works
Remarks
So while this Data Binding concept on a whole is easy on the developer, it is quite heavy on the
Browser since Angular listens to every event change and runs the Digest Cycle. Because of this,
whenever we attach some model to the view, make sure that Scope is as optimized as possible
Examples
Data Binding Example
<p ng-bind="message"></p>
At a later point of time , even if the message model is updated , that updated value is reflected in
the HTML element. When angular compiles the template "Hello World" will be attached to the
innerHTML of the current world. Angular maintains a Watching mechanism of all the directives
atttached to the view. It has a Digest Cycle mechanism where it iterates through the Watchers
array, it will update the DOM element if there is a change in the previous value of the model.
There is no periodic checking of Scope whether there is any change in the Objects attached to it.
Not all the objects attached to scope are watched . Scope prototypically maintains a
$$WatchersArray . Scope only iterates through this WatchersArray when $digest is called .
1. First one is a watcher function which just returns the object or we can just add an
expression.
2. Second one is a listener function which will be called when there is a change in
the object. All the things like DOM changes will be implemented in this function.
3. The third being an optional parameter which takes in a boolean . If its true ,
angular deep watches the object & if its false Angular just does a reference
watching on the object. Rough Implementation of $watch looks like this
https://riptutorial.com/ 149
Scope.prototype.$watch = function(watchFn, listenerFn) {
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() { },
last: initWatchVal // initWatchVal is typically undefined
};
this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers
};
There is an interesting thing in Angular called Digest Cycle. The $digest cycle starts as a result of
a call to $scope.$digest(). Assume that you change a $scope model in a handler function through
the ng-click directive. In that case AngularJS automatically triggers a $digest cycle by calling
$digest().In addition to ng-click, there are several other built-in directives/services that let you
change models (e.g. ng-model, $timeout, etc) and automatically trigger a $digest cycle. The rough
implementation of $digest looks like this.
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
If we use JavaScript’s setTimeout() function to update a scope model, Angular has no way of
knowing what you might change. In this case it’s our responsibility to call $apply() manually, which
triggers a $digest cycle. Similarly, if you have a directive that sets up a DOM event listener and
changes some models inside the handler function, you need to call $apply() to ensure the changes
take effect. The big idea of $apply is that we can execute some code that isn't aware of Angular,
that code may still change things on the scope. If we wrap that code in $apply , it will take care of
calling $digest(). Rough implementation of $apply().
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
https://riptutorial.com/ 150
};
https://riptutorial.com/ 151
Chapter 30: HTTP Interceptor
Introduction
The $http service of AngularJS allows us to communicate with a backend and make HTTP
requests. There are cases where we want to capture every request and manipulate it before
sending it to the server. Other times we would like to capture the response and process it before
completing the call. Global http error handling can be also a good example of such need.
Interceptors are created exactly for such cases.
Examples
Getting Started
Angular's builtin $http service allows us to send HTTP requests. Oftentime, the need arise to do
things before or after a request, for example adding to each request an authentication token or
creating a generic error handling logic.
<!DOCTYPE html>
<html>
<head>
<title>Angular Interceptor Sample</title>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script src="app.js"></script>
<script src="appController.js"></script>
<script src="genericInterceptor.js"></script>
</head>
<body ng-app="interceptorApp">
<div ng-controller="appController as vm">
<button ng-click="vm.sendRequest()">Send a request</button>
</div>
</body>
</html>
interceptorApp.config(function($httpProvider) {
$httpProvider.interceptors.push('genericInterceptor');
});
(function() {
https://riptutorial.com/ 152
'use strict';
function appController($http) {
var vm = this;
vm.sendRequest = function(){
$http.get('http://google.com').then(function(response){
console.log(response);
});
};
}
angular.module('interceptorApp').controller('appController',['$http', appController]);
})();
(function() {
"use strict";
function genericInterceptor($q) {
this.responseError = function (response) {
return $q.reject(response);
};
this.requestError = function(request){
if (canRecover(rejection)) {
return responseOrNewPromise
}
return $q.reject(rejection);
};
this.response = function(response){
return response;
};
this.request = function(config){
return config;
}
}
angular.module('interceptorApp').service('genericInterceptor', genericInterceptor);
})();
The 'genericInterceptor' cover the possible functions which we can override adding extra behavior
to our application.
https://riptutorial.com/ 153
<div class="flashmessage" ng-if="isVisible">
{{flashMessage}}
</div>
Script File
In the config method of angular module, inject the httpProvider, the httpProvider has an interceptor
array property, push the custom interceptor, In the current example the custom interceptor
intercepts only the response and calls a method attached to rootScope.
interceptorTest.config(['$httpProvider',function ($httpProvider) {
$httpProvider.interceptors.push(["$rootScope",function ($rootScope) {
return { //intercept only the response
'response': function (response)
{
$rootScope.showFeedBack(response.status,response.data.message);
return response;
}
};
}]);
}])
Since only providers can be injected into the config method of an angular module (that is
httpProvider and not the rootscope), declare the method attached to rootscope inside the run
method of angular module.
Also display the message inside $timeout so that the message will have the flash property, that is
disappearing after a threshold time. In our example its 3000 ms.
interceptorTest.run(["$rootScope","$timeout",function($rootScope,$timeout){
$rootScope.showFeedBack = function(status,message){
$rootScope.isVisible = true;
$rootScope.flashMessage = message;
$timeout(function(){$rootScope.isVisible = false },3000)
}
}]);
Common pitfalls
Trying to inject $rootScope or any other services inside config method of angular module, the
lifecycle of angular app doesnt allow that and unknown provider error will be thrown. Only
providers can be injected in config method of the angular module
https://riptutorial.com/ 154
Chapter 31: Lazy loading
Remarks
1. If your lazy loaded dependencies require other lazy loaded dependencies make sure you
load them in the right order!
angular.module('lazy', [
'alreadyLoadedDependency1',
'alreadyLoadedDependency2',
...
{
files: [
'path/to/lazily/loaded/dependency1.js',
'path/to/lazily/loaded/dependency2.js', //<--- requires lazily loaded dependency1
'path/to/lazily/loaded/dependency.css'
],
serie: true //Sequential load instead of parallel
}
]);
Examples
Preparing your project for lazy loading
After including oclazyload.js in your index file, declare ocLazyLoad as a dependency in app.js
//Make sure you put the correct dependency! it is spelled different than the service!
angular.module('app', [
'oc.lazyLoad',
'ui-router'
])
Usage
In order to lazily load files inject the $ocLazyLoad service into a controller or another service
.controller('someCtrl', function($ocLazyLoad) {
$ocLazyLoad.load('path/to/file.js').then(...);
});
Other variation:
$ocLazyLoad.load([
'bower_components/bootstrap/dist/js/bootstrap.js',
'bower_components/bootstrap/dist/css/bootstrap.css',
'partials/template1.html'
https://riptutorial.com/ 155
]);
UI-Router:
.state('profile', {
url: '/profile',
controller: 'profileCtrl as vm'
resolve: {
module: function($ocLazyLoad) {
return $ocLazyLoad.load([
'path/to/profile/module.js',
'path/to/profile/style.css'
]);
}
}
});
ngRoute:
.when('/profile', {
controller: 'profileCtrl as vm'
resolve: {
module: function($ocLazyLoad) {
return $ocLazyLoad.load([
'path/to/profile/module.js',
'path/to/profile/style.css'
]);
}
}
});
The following syntax allows you to specify dependencies in your module.js instead of explicit
specification when using the service
//lazy_module.js
angular.module('lazy', [
'alreadyLoadedDependency1',
'alreadyLoadedDependency2',
...
[
'path/to/lazily/loaded/dependency.js',
'path/to/lazily/loaded/dependency.css'
]
]);
Note: this syntax will only work for lazily loaded modules!
https://riptutorial.com/ 156
Using the directive
<div oc-lazy-load="['path/to/lazy/loaded/directive.js',
'path/to/lazy/loaded/directive.html']">
</div>
https://riptutorial.com/ 157
Chapter 32: Migration to Angular 2+
Introduction
AngularJS has been totally rewritten using the TypeScript language and renamed to just Angular.
There is a lot that can be done to an AngularJS app to ease the migration process. As the official
upgrade guide says, several "preparation steps" can be performed to refactor your app, making it
better and closer to the new Angular style.
Examples
Converting your AngularJS app into a componend-oriented structure
In the new Angular framework, Components are the main building blocks that compose the user
interface. So one of the first steps that helps an AngularJS app to be migrated to the new Angular
is to refactor it into a more component-oriented structure.
Components were also introduced in the old AngularJS starting from version 1.5+. Using
Components in an AngularJS app will not only make its structure closer to the new Angular 2+, but
it will also make it more modular and easier to maintain.
Before going further I recommend to look at the official AngularJS documentation page about
Components, where their advantages and usage are well explained.
I would rather mention some tips about how to convert the old ng-controller oriented code to the
new component oriented style.
Assume that we have a piece of code assigned to a controller, named UserListController, and we
want to make a component of it, which we'll name UserListComponent.
current HTML:
https://riptutorial.com/ 158
{{ user }}
</li>
</ul>
</div>
current JavaScript:
this.someFunction = function() {
// ...
}
// ...
}
new HTML:
<user-list></user-list>
new JavaScript:
app.component("UserList", {
templateUrl: 'user-list.html',
controller: UserListController
});
function UserListController(SomeService) {
this.someFunction = function() {
// ...
}
// ...
}
Note how we are no longer injecting $scope into the controller function and we are now declaring
this.myUserList instead of $scope.myUserList;
<ul>
<li ng-repeat="user in $ctrl.myUserList">
{{ user }}
</li>
</ul>
Note how we are now referring to the variable myUserList, which belongs to the controller, using
$ctrl.myUserList from the html instead of $scope.myUserList.
https://riptutorial.com/ 159
That is because, as you probably figured out after reading the documentation, $ctrl in the
template now refers to the controller function.
$stateProvider
.state('users', {
url: '/users',
templateUrl: 'user-list.html',
controller: 'UserListController'
})
// ..
$stateProvider
.state('users', {
url: '/',
template: '<user-list></user-list>'
})
// ..
What's next?
Now that you have a component containing your app (whether it contains the entire application or
a part of it, like a view), you should now start to break your component into multiple nested
components, by wrapping parts of it into new sub-components, and so on.
After reading the Component documentation you should already know how to use all those
component features, but if you need a concrete example of a real simple app, you can check this.
Also, if inside your component's controller you have some functions that hold a lot of logic code, a
good idea can be considering to move that logic into services.
Conclusion
Adopting a component-based approach pushes your AngularJS one step closer to migrate it to the
https://riptutorial.com/ 160
new Angular framework, but it also makes it better and much more modular.
Of course there are a lot of other steps you can do to go further into the new Angular 2+ direction,
which I will list in the following examples.
By using a module loader like Webpack we can benefit the built-in module system available in
ES6 (as well as in TypeScript). We can then use the import and export features that allow us to
specify what pieces of code can we are going to share between different parts of the application.
When we then take our applications into production, module loaders also make it easier to
package them all up into production bundles with batteries included.
https://riptutorial.com/ 161
Chapter 33: Modules
Examples
Modules
Module serves as a container of different parts of your app such as controllers, services, filters,
directives, etc. Modules can be referenced by other modules through Angular's dependency
injection mechanism.
Creating a module:
angular
.module('app', []);
Array [] passed in above example is the list of modules app depends on, if there are no
dependencies then we pass Empty Array i.e. [].
angular.module('app', [
'app.auth',
'app.dashboard'
]);
Referencing a module:
angular
.module('app');
Modules
Module is a container for various parts of your applications - controller, services, filters, directive,
etc.
declare a module
https://riptutorial.com/ 162
// if there are any required dependancies,
// then you can add in module, Like ['ngAnimate']
app.controller('myController', function() {
angular.module('myModule', []).
config(function(injectables) {
// here you can only inject providers in to config blocks.
});
2. Run Blocks:- get executed after the injector is created and are used to start the application.
angular.module('myModule', []).
run(function(injectables) {
// here you can only inject instances in to config blocks.
});
https://riptutorial.com/ 163
Chapter 34: ng-class directive
Examples
Three types of ng-class expressions
1. String
<span ng-class="MyClass">Sample Text</span>
Specifying an expression that evaluates to a string tells Angular to treat it as a $scope variable.
Angular will check the $scope and look for a variable called "MyClass". Whatever text is contained
in "MyClass" will become the actual class name that is applied to this <span>. You can specify
multiple classes by separating each class with a space.
In your controller, you may have a definition that looks like this:
Angular will evaluate the expression MyClass and find the $scope definition. It will apply the three
classes "bold-red", "deleted", and "error" to the <span> element.
Specifying classes this way lets you easily change the class definitions in your controller. For
example, you may need to change the class based on other user interactions or new data that is
loaded from the server. Also, if you have a lot of expressions to evaluate, you can do so in a
function that defines the final list of classes in a $scope variable. This can be easier than trying to
squeeze many evaluations into the ng-class attribute in your HTML template.
2. Object
This is the most commonly-used way of defining classes using ng-class because it easily lets you
specify evaluations that determine which class to use.
Specify an object containing key-value pairs. The key is the class name that will be applied if the
value (a conditional) evaluates as true.
<style>
.red { color: red; font-weight: bold; }
.blue { color: blue; }
.green { color: green; }
.highlighted { background-color: yellow; color: black; }
https://riptutorial.com/ 164
</style>
<span ng-class="{ red: ShowRed, blue: ShowBlue, green: ShowGreen, highlighted: IsHighlighted
}">Sample Text</span>
3. Array
An expression that evaluates to an array lets you use a combination of strings (see #1 above)
and conditional objects (#2 above).
<style>
.bold { font-weight: bold; }
.strike { text-decoration: line-through; }
.orange { color: orange; }
</style>
This creates a text input field bound to the scope variable UserStyle which lets the user type in any
class name(s). These will be dynamically applied to the <p> element as the user types. Also, the
user can click on the checkbox that is data-bound to the warning scope variable. This will also be
dynamically applied to the <p> element.
https://riptutorial.com/ 165
Chapter 35: ng-repeat
Introduction
The ngRepeat directive instantiates a template once per item from a collection. The collection must
be an array or an object. Each template instance gets its own scope, where the given loop variable
is set to the current collection item, and $index is set to the item index or key.
Syntax
• <element ng-repeat="expression"></element>
• <div ng-repeat="(key, value) in myObj">...</div>
• <div ng-repeat="variable in expression">...</div>
Parameters
Variable Details
$middle boolean true if the repeated element is between the first and last in the iterator.
$even boolean true if the iterator position $index is even (otherwise false).
$odd boolean true if the iterator position $index is odd (otherwise false).
Remarks
AngularJS provides these parameters as special variables that are available in the ng-repeat
expression and anywhere inside of the HTML tag on which the ng-repeat lives.
Examples
Iterating over object properties
For example
https://riptutorial.com/ 166
{{n}}
</div>
ngRepeat uses $watchCollection to detect changes in the collection. When a change happens,
ngRepeat then makes the corresponding changes to the DOM:
• When an item is added, a new instance of the template is added to the DOM.
• When an item is removed, its template instance is removed from the DOM.
• When items are reordered, their respective templates are reordered in the DOM.
Duplicates
$scope.numbers = ['1','1','2','3','4'];
<ul>
<li ng-repeat="n in numbers track by $index">
{{n}}
</li>
</ul>
ng-repeat-start + ng-repeat-end
AngularJS 1.2 ng-repeat handle multiple elements with ng-repeat-start and ng-repeat-end:
// table items
$scope.tableItems = [
{
row1: 'Item 1: Row 1',
row2: 'Item 1: Row 2'
},
{
row1: 'Item 2: Row 1',
row2: 'Item 2: Row 2'
}
];
// template
<table>
<th>
<td>Items</td>
</th>
<tr ng-repeat-start="item in tableItems">
<td ng-bind="item.row1"></td>
</tr>
<tr ng-repeat-end>
<td ng-bind="item.row2"></td>
</tr>
</table>
https://riptutorial.com/ 167
Output:
Items
Item 1: Row 1
Item 1: Row 2
Item 2: Row 1
Item 2: Row 2
https://riptutorial.com/ 168
Chapter 36: ng-style
Introduction
The 'ngStyle' directive allows you to set CSS style on an HTML element conditionally. Much like
how we could use style attribute on HTML element in non-AngularJS projects, we can use ng-
style in angularjs do apply styles based on some boolean condition.
Syntax
• <ANY ng-style="expression"></ANY >
Examples
Use of ng-style
Below example changes the opacity of the image based on the "status" parameter.
https://riptutorial.com/ 169
Chapter 37: ng-view
Introduction
ng-view is one of in-build directive that angular uses as a container to switch between views. {info}
ngRoute is no longer a part of the base angular.js file, so you'll need to include the angular-route.js
file after your the base angular javascript file. We can configure a route by using the “when”
function of the $routeProvider. We need to first specify the route, then in a second parameter
provide an object with a templateUrl property and a controller property.
Examples
ng-view
ng-view is a directive used with $route to render a partial view in the main page layout. Here in this
example, Index.html is our main file and when user lands on "/" route the templateURL home.html
will be rendered in Index.html where ng-view is mentioned.
angular.module('ngApp', ['ngRoute'])
.config(function($routeProvider){
$routeProvider.when("/",
{
templateUrl: "home.html",
controller: "homeCtrl"
}
);
});
angular.module('ngApp').controller('homeCtrl',['$scope', function($scope) {
$scope.welcome= "Welcome to stackoverflow!";
}]);
//Index.html
<body ng-app="ngApp">
<div ng-view></div>
</body>
Registration navigation
var Registration=angular.module("myApp",["ngRoute"]);
https://riptutorial.com/ 170
Registration.config(function($routeProvider) {
});
3. finally we integrating the route, we define "/add" routing to the application in case application
get "/add" it divert to regi.htm
Registration.config(function($routeProvider) {
$routeProvider
.when("/add", {
templateUrl : "regi.htm"
})
});
https://riptutorial.com/ 171
Chapter 38: Performance Profiling
Examples
All About Profiling
What is Profiling?
By definition Profiling is a form of dynamic program analysis that measures, for example, the
space (memory) or time complexity of a program, the usage of particular instructions, or the
frequency and duration of function calls.
Why is it necessary?
Profiling is important because you can’t optimise effectively until you know what your program is
spending most of its time doing. Without measuring your program execution time (profiling), you
won’t know if you’ve actually improved it.
This includes a comprehensive set of tools to be used for profiling.You can go deep to find
out bottlenecks in your javascript file, css files, animations, cpu consumption, memory leaks,
network, security etc.
Make a Timeline recording and look for suspiciously long Evaluate Script events. If you find
any, you can enable the JS Profiler and re-do your recording to get more detailed information
about exactly which JS functions were called and how long each took. Read more...
It's an outdated add-on for chrome browser though it's stable and can be used to monitor
models, performance, dependencies for an angular application. It works fine for small scale
application and can give you an insight of what does scope variable holds at various levels. It
tells you about active watchers, watch expressions, watch collections in the app.
6. Use the following code to manually find out the number of watchers in your angular app
(credit to @Words Like Jared Number of watchers)
https://riptutorial.com/ 172
(function() {
var root = angular.element(document.getElementsByTagName('body')),
watchers = [],
f = function(element) {
angular.forEach(['$scope', '$isolateScope'], function(scopeProperty) {
if(element.data() && element.data().hasOwnProperty(scopeProperty)) {
angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) {
watchers.push(watcher);
});
}
});
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
7. There are several online tools/websites available which facilitates wide range of
functionalities to create a profile of your application.
With this you can run a free website speed test from multiple locations around the globe
using real browsers (IE and Chrome) and at real consumer connection speeds. You can run
simple tests or perform advanced testing including multi-step transactions, video capture,
content blocking and much more.
Next Steps:
Done with Profiling. It only brings you half way down the road. The very next task is to actually turn
your findings into action items to optimise your application. See this documentation on how you
can improve the performance of your angular app with simple tricks.
Happy Coding :)
https://riptutorial.com/ 173
Chapter 39: Prepare for Production - Grunt
Examples
View preloading
When the first time view is requested, normally Angular makes XHR request to get that view. For
mid-size projects, the view count can be significant and it can slow down the application
responsiveness.
The good practice is to pre-load all the views at once for small and mid size projects. For larger
projects it is good to aggregate them in some meaningful bulks as well, but some other methods
can be handy to split the load. To automate this task it is handy to use Grunt or Gulp tasks.
To pre-load the views, we can use $templateCache object. That is an object, where angular stores
every received view from the server.
It is possible to use html2js module, that will convert all our views to one module - js file. Then we
will need to inject that module into our application and that's it.
To create concatenated file of all the views we can use this task
grunt.initConfig({
pkg: require('./package.json'),
//section that sets up the settings for concatenation of the html files into one
file
html2js: {
options: {
base: '',
module: 'app.templates', //new module name
singleModule: true,
useStrict: true,
htmlmin: {
collapseBooleanAttributes: true,
collapseWhitespace: true
}
},
main: {
src: viewLocation,
dest: 'build/app.templates.js'
}
},
//this section is watching for changes in view files, and if there was a change,
it will regenerate the production file. This task can be handy during development.
watch: {
views:{
files: viewLocation,
tasks: ['buildHTML']
},
https://riptutorial.com/ 174
}
});
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
To use this way of concatination, you need to make 2 changes: In your index.html file you need to
reference the concatenated view file
<script src="build/app.templates.js"></script>
In the file, where you are declaring your app, you need to inject the dependency
angular.module('app', ['app.templates'])
If you are using popular routers like ui-router, there are no changes in the way, how you are
referencing templates
.state('home', {
url: '/home',
views: {
"@": {
controller: 'homeController',
//this will be picked up from $templateCache
templateUrl: 'app/views/home.html'
},
}
})
Script optimisation
It is good practice to combine JS files together and minify them. For larger project there could
be hundreds of JS files and it adds unnecessary latency to load each file separately from the
server.
For angular minification it is required to to have all functions annotated. That in necessary for
Angular dependency injection proper minificaiton. (During minification, function names and
variables will be renamed and it will break dependency injection if no extra actions will be taken.)
During minificaiton $scope and myService variables will be replaced by some other values. Angular
dependency injection works based on the name, as a result, these names shouldn't change
https://riptutorial.com/ 175
Angular will understand the array notation, because minification won't replace string literals.
module.exports = function (grunt) { //set up the location of your scripts here for reusing it in code
var scriptLocation = ['app/scripts/*.js'];
grunt.initConfig({
pkg: require('./package.json'),
//add necessary annotations for safe minification
ngAnnotate: {
angular: {
src: ['staging/concatenated.js'],
dest: 'staging/anotated.js'
}
},
//combines all the files into one file
concat: {
js: {
src: scriptLocation,
dest: 'staging/concatenated.js'
}
},
//final uglifying
uglify: {
options: {
report: 'min',
mangle: false,
sourceMap:true
},
my_target: {
files: {
'build/app.min.js': ['staging/anotated.js']
}
}
},
//this section is watching for changes in JS files, and if there was a change, it will
regenerate the production file. You can choose not to do it, but I like to keep concatenated
version up to date
watch: {
scripts: {
files: scriptLocation,
tasks: ['buildJS']
}
}
});
https://riptutorial.com/ 176
grunt.loadNpmTasks('grunt-contrib-concat');
//to watch for changes and if the file has been changed, regenerate the file
grunt.loadNpmTasks('grunt-contrib-watch');
//task that sequentially executes all steps to prepare JS file for production
//concatinate all JS files
//annotate JS file (prepare for minification
//uglify file
grunt.registerTask('buildJS', ['concat:js', 'ngAnnotate', 'uglify']);
};
https://riptutorial.com/ 177
Chapter 40: Print
Remarks
Create an ng-hide class in css file. ng-show/hide will not work without the class.
More details
Examples
Print Service
Service:
hiddenFrame.contentWindow.printAndRemove = function() {
hiddenFrame.contentWindow.print();
$(hiddenFrame).remove();
deferred.resolve();
};
$rootScope.isBeingPrinted = true;
https://riptutorial.com/ 178
$http.get(templateUrl).success(function(template){
var printScope = $rootScope.$new()
angular.extend(printScope, data);
var element = $compile($('<div>' + template + '</div>'))(printScope);
var waitForRenderAndPrint = function() {
if(printScope.$$phase || $http.pendingRequests.length) {
$timeout(waitForRenderAndPrint, 1000);
} else {
// Replace printHtml with openNewWindow for debugging
printHtml(element.html());
printScope.$destroy();
}
};
waitForRenderAndPrint();
});
};
return {
print : print,
printFromScope : printFromScope
}
}
]);
Controller :
https://riptutorial.com/ 179
Chapter 41: Profiling and Performance
Examples
7 Simple Performance Improvements
Try to avoid nested repeats as much as possible. One way to improve the performance of ng-
repeat is to use track by $index (or some other id field). By default, ng-repeat tracks the whole
object. With track by, Angular watches the object only by the $index or object id.
Use other approaches like pagination, virtual scrolls, infinite scrolls or limitTo: begin whenever
possible to avoid iterating over large collections.
2) Bind once
Angular has bidirectional data binding. It comes with a cost of being slow if used too much.
Slower Performance
<div ng-bind="::my.data"></div>
https://riptutorial.com/ 180
<!-- Use single binding notation in ng-repeat where only list display is needed -->
<div ng-repeat="user in ::userCollection">
{{::user.data}}
</div>
Using the "bind once" notation tells Angular to wait for the value to stabilize after the first series of
digest cycles. Angular will use that value in the DOM, then remove all watchers so that it becomes
a static value and is no longer bound to the model.
This ng-bind is a directive and will place a watcher on the passed variable. So the ng-bind will only
apply, when the passed value does actually change.
The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not
necessary.
Avoid this:
Better approach
app.controller('bigCalulations', function(valueService) {
// bad, because this is called in every digest loop
this.calculateMe = function() {
var t = 0;
for(i = 0; i < 1000; i++) {
t += i;
}
return t;
}
// good, because this is executed just once and logic is separated in service to keep
the controller light
this.preCalulatedValue = valueService.valueCalculation(); // returns 499500
https://riptutorial.com/ 181
});
4) Watchers
Watchers tremendously drop performance. With more watchers, the digest loop will take longer
and the UI will slow down. If the watcher detects change, it will kick off the digest loop and re-
render the view.
There are three ways to do manual watching for variable changes in Angular.
$watchCollection() - watches for changes in collection (watches more than regular $watch)
$watch(..., true)- Avoid this as much as possible, it will perform "deep watch" and will decline
the performance (watches more than watchCollection)
Note that if you are binding variables in the view you are creating new watches - use
{{::variable}} to prevent creating a watch, especially in loops.
As a result you need to track how many watchers you are using. You can count the watchers with
this script (credit to @Words Like Jared Number of watchers)
(function() {
var root = angular.element(document.getElementsByTagName('body')),
watchers = [],
f = function(element) {
angular.forEach(['$scope', '$isolateScope'], function(scopeProperty) {
if(element.data() && element.data().hasOwnProperty(scopeProperty)) {
angular.forEach(element.data()[scopeProperty].$$watchers, function(watcher) {
watchers.push(watcher);
});
}
});
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
https://riptutorial.com/ 182
5) ng-if / ng-show
These functions are very similar in behavior. ng-if removes elements from the DOM while ng-show
only hides the elements but keeps all handlers. If you have parts of the code you do not want to
show, use ng-if.
It depends on the type of usage, but often one is more suitable than the other.
6) Disable debugging
By default, bind directives and scopes leave extra classes and markup in the code to assist with
various debugging tools. Disabling this option means that you no longer render these various
elements during the digest cycle.
You might wonder about the performance cost associated with such string parsing of all injectable
functions. Angular takes care of this by caching the $inject property after the first time. So this
doesn’t happen everytime a function needs to be invoked.
PRO TIP: If you are looking for the approach with the best performance, go with the $inject
property annotation approach. This approach entirely avoids the function definition parsing
because this logic is wrapped within the following check in the annotate function: if (!($inject =
fn.$inject)). If $inject is already available, no parsing required!
https://riptutorial.com/ 183
var DemoController = function (s, h) {
h.get('https://api.github.com/users/angular/repos').success(function (repos) {
s.repos = repos;
});
}
// $inject property annotation
DemoController['$inject'] = ['$scope', '$http'];
app.controller('DemoController', DemoController);
PRO TIP 2: You can add an ng-strict-di directive on the same element as ng-app to opt into strict
DI mode which will throw an error whenever a service tries to use implicit annotations. Example:
angular.bootstrap(document, ['DemoApp'], {
strictDi: true
});
Bind Once
Angular has reputation for having awesome bidirectional data binding. By default, Angular
continuously synchronizes values bound between model and view components any time data
changes in either the model or view component.
This comes with a cost of being a bit slow if used too much. This will have a larger performance
hit:
Add two colons :: before the variable name to use one-time binding. In this case, the value only
gets updated once my.data is defined. You are explicitly pointing not to watch for data changes.
Angular won't perform any value checks, resulting with fewer expressions being evaluated on
each digest cycle.
{{::my.data}}
<span ng-bind="::my.data"></span>
<span ng-if="::my.data"></span>
<span ng-repeat="item in ::my.data">{{item}}</span>
<span ng-class="::{ 'my-class': my.data }"></div>
Note: This however removes the bi-directional data binding for my.data, so whenever this field
changes in your application, the same won't be reflected in the view automatically. So use it only
for values that won't change throughout the lifespan of your application.
https://riptutorial.com/ 184
AngularJS has digest loop and all your functions in a view and filters are executed every time the
digest cycle is run. The digest loop will be executed whenever the model is updated and it can
slow down your app (filter can be hit multiple times, before the page is loaded).
Better approach
.controller("bigCalulations", function(valueService) {
// bad, because this is called in every digest loop
this.calculateMe = function() {
var t = 0;
for(i = 0; i < 1000; i++) {
t = t + i;
}
return t;
}
//good, because it is executed just once and logic is separated in service to keep the
controller light
this.preCalulatedValue = valueService.caluclateSumm(); // returns 499500
});
Watchers
Watchers needed for watch some value and detect that this value is changed.
After call $watch() or $watchCollection new watcher add to internal watcher collection in current
scope.
Watcher is a simple function, which is called on every digest cycle, and returns some value.
Angular checks the returned value, if it is not the same as it was on the previous call - a callback
that was passed in second parameter to function $watch() or $watchCollection will be executed.
(function() {
angular.module("app", []).controller("ctrl", function($scope) {
$scope.value = 10;
$scope.$watch(
function() { return $scope.value; },
https://riptutorial.com/ 185
function() { console.log("value changed"); }
);
}
})();
Watchers are performance killers. The more watchers you have, the longer they take to make a
digest loop, the slower UI. If a watcher detects changes, it will kick off the digest loop
(recalculation on all screen)
There are three ways to do manual watch for variable changes in Angular.
$watchCollection() - watches for changes in collection (watches more than regular $watch)
- Avoid this as much as possible, it will perform "deep watch" and will kill the
$watch(..., true)
performance (watches more than watchCollection)
Note that if you are binding variables in the view, you are creating new watchers - use
{{::variable}} not to create watcher, especially in loops
As a result you need to track how many watchers are you using. You can count the watchers with
this script (credit to @Words Like Jared - How to count total number of watches on a page?
(function() {
var root = angular.element(document.getElementsByTagName("body")),
watchers = [];
var f = function(element) {
angular.forEach(element.children(), function(childElement) {
f(angular.element(childElement));
});
};
f(root);
console.log(watchersWithoutDuplicates.length);
https://riptutorial.com/ 186
})();
If you don't want to create your own script, there is an open source utility called ng-stats that uses
a real-time chart embedded into the page to give you insight into the number of watches Angular is
managing, as well as the frequency and duration of digest cycles over time. The utility exposes a
global function named showAngularStats that you can call to configure how you want the chart to
work.
showAngularStats({
"position": "topleft",
"digestTimeThreshold": 16,
"autoload": true,
"logDigest": true,
"logWatches": true
});
The example code above displays the following chart on the page automatically (interactive demo
).
ng-if vs ng-show
These functions are very similar in behaviour. The difference is that ng-if removes elements from
the DOM. If there are large parts of the code that will not be shown, then ng-if is the way to go.
ng-show will only hide the elements but will keep all the handlers.
ng-if
The ngIf directive removes or recreates a portion of the DOM tree based on an expression. If the
expression assigned to ngIf evaluates to a false value then the element is removed from the DOM,
otherwise a clone of the element is reinserted into the DOM.
ng-show
The ngShow directive shows or hides the given HTML element based on the expression provided
to the ngShow attribute. The element is shown or hidden by removing or adding the ng-hide CSS
class onto the element.
Example
https://riptutorial.com/ 187
<div ng-repeat="user in userCollection">
<p ng-if="user.hasTreeLegs">I am special
<!-- some complicated DOM -->
</p>
<p ng-show="user.hasSubscribed">I am aweosme
<!-- switch this setting on and off -->
</p>
</div>
Conclusion
It depends from the type of usage, but often one is more suitable than the other (e.g., if 95% of the
time the element is not needed, use ng-if; if you need to toggle the DOM element's visibility, use
ng-show).
Note: ng-if creates a new isolated scope, whereas ng-show and ng-hide don't. Use $parent.property
if parent scope property is not directly accessible in it.
<div ng-controller="ExampleController">
<form name="userForm">
Name:
<input type="text" name="userName"
ng-model="user.name"
ng-model-options="{ debounce: 1000 }" />
<button ng-click="userForm.userName.$rollbackViewValue();
user.name=''">Clear</button><br />
</form>
<pre>user.name = </pre>
</div>
The above example we are setting a debounce value of 1000 milliseconds which is 1 second. This
is a considerable delay, but will prevent the input from repeatedly thrashing ng-model with many
$digest cycles.
By using debounce on your input fields and anywhere else where an instant update is not
required, you can increase the performance of your Angular apps quite substantially. Not only can
you delay by time, but you can also delay when the action gets triggered. If you don’t want to
update your ng-model on every keystroke, you can also update on blur as well.
Always deregister listeners registered on other scopes other than the current
scope
You must always unregister scopes other then your current scope as shown below:
https://riptutorial.com/ 188
$scope.$parent.$on(...);
You don't have to deregister listners on current scope as angular would take care of it:
listeners will remain in memory if you navigate to another controller. This will create
$rootScope.$on
a memory leak if the controller falls out of scope.
Don't
angular.module('app').controller('badExampleController', badExample);
badExample.$inject = ['$scope', '$rootScope'];
Do
angular.module('app').controller('goodExampleController', goodExample);
goodExample.$inject = ['$scope', '$rootScope'];
https://riptutorial.com/ 189
Chapter 42: Providers
Syntax
• constant(name, value);
• value(name, value);
• factory(name, $getFn);
• service(name, constructor);
• provider(name, provider);
Remarks
Providers are singleton objects that can be injected, for example, into other services, controllers
and directives. All providers are registered using different "recipes", where Provider is the most
flexible one. All possible recipes are:
• Constant
• Value
• Factory
• Service
• Provider
Services, Factories and Providers are all lazy initialized, component is initialized only if application
depends on it.
Decorators are closely related to Providers. Decorators are used to intercept service or factory
creation in order to change it's behavior or override (parts of) it.
Examples
Constant
angular.module('app',[])
.constant('endpoint', 'http://some.rest.endpoint') // define
.config(function(endpoint) {
// do something with endpoint
// available in both config- and run phases
})
.controller('MainCtrl', function(endpoint) { // inject
var vm = this;
vm.endpoint = endpoint; // usage
});
https://riptutorial.com/ 190
<div>endpoint = {{ ::vm.endpoint }}</div>
</body>
endpoint = http://some.rest.endpoint
Value
angular.module('app',[])
.value('endpoint', 'http://some.rest.endpoint') // define
.run(function(endpoint) {
// do something with endpoint
// only available in run phase
})
.controller('MainCtrl', function(endpoint) { // inject
var vm = this;
vm.endpoint = endpoint; // usage
});
endpoint = http://some.rest.endpoint
Factory
The Factory recipe constructs a new service using a function with zero or more
arguments (these are dependencies on other services). The return value of this
function is the service instance created by this recipe.
Factory can create a service of any type, whether it be a primitive, object literal,
function, or even an instance of a custom type.
angular.module('app',[])
.factory('endpointFactory', function() {
return {
get: function() {
return 'http://some.rest.endpoint';
}
};
})
.controller('MainCtrl', function(endpointFactory) {
var vm = this;
vm.endpoint = endpointFactory.get();
});
https://riptutorial.com/ 191
<body ng-controller="MainCtrl as vm">
<div>endpoint = {{::vm.endpoint }}</div>
</body>
endpoint = http://some.rest.endpoint
Service
The Service recipe produces a service just like the Value or Factory recipes, but it does
so by invoking a constructor with the new operator. The constructor can take zero or
more arguments, which represent dependencies needed by the instance of this type.
angular.module('app',[])
.service('endpointService', function() {
this.get = function() {
return 'http://some.rest.endpoint';
};
})
.controller('MainCtrl', function(endpointService) {
var vm = this;
vm.endpoint = endpointService.get();
});
endpoint = http://some.rest.endpoint
Provider
The Provider recipe is syntactically defined as a custom type that implements a $get
method.
You should use the Provider recipe only when you want to expose an API for
application-wide configuration that must be made before the application starts. This is
usually interesting only for reusable services whose behavior might need to vary
slightly between applications.
angular.module('app',[])
.provider('endpointProvider', function() {
var uri = 'n/a';
this.set = function(value) {
uri = value;
};
https://riptutorial.com/ 192
this.$get = function() {
return {
get: function() {
return uri;
}
};
};
})
.config(function(endpointProviderProvider) {
endpointProviderProvider.set('http://some.rest.endpoint');
})
.controller('MainCtrl', function(endpointProvider) {
var vm = this;
vm.endpoint = endpointProvider.get();
});
endpoint = http://some.rest.endpoint
endpoint = n/a
https://riptutorial.com/ 193
Chapter 43: Routing using ngRoute
Remarks
The ngRoute is a build-in module provides routing and deeplinking services and directives for
angular apps.
Examples
Basic example
This example shows setting up a small application with 3 routes, each with it's own view and
controller, using the controllerAs syntax.
app.js
angular.module('myApp', ['ngRoute'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.config(function($routeProvider) {
$routeProvider
.when('/one', {
templateUrl: 'view-one.html',
controller: 'controllerOne',
controllerAs: 'ctrlOne'
})
.when('/two', {
templateUrl: 'view-two.html',
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.when('/three', {
templateUrl: 'view-three.html',
controller: 'controllerThree',
controllerAs: 'ctrlThree'
https://riptutorial.com/ 194
})
// redirect to here if no other routes match
.otherwise({
redirectTo: '/one'
});
});
Then in our HTML we define our navigation using <a> elements with href, for a route name of
helloRoute we will route as <a href="#/helloRoute">My route</a>
We also provide our view with a container and the directive ng-view to inject our routes.
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a href="#/one">View One</a>
<a href="#/two">View Two</a>
<a href="#/three">View Three</a>
</nav>
<!-- views will be injected here -->
<div ng-view></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
This example extends the basic example passing parameters in the route in order to use them in
the controller
To do so we need to:
app.js
angular.module('myApp', ['ngRoute'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
https://riptutorial.com/ 195
})
.controller('controllerThree', ['$routeParams', function($routeParams) {
var routeParam = $routeParams.paramName
if ($routeParams.message) {
// If a param called 'message' exists, we show it's value as the message
this.message = $routeParams.message;
} else {
// If it doesn't exist, we show a default message
this.message = 'Hello world from Controller Three!';
}
}])
.config(function($routeProvider) {
$routeProvider
.when('/one', {
templateUrl: 'view-one.html',
controller: 'controllerOne',
controllerAs: 'ctrlOne'
})
.when('/two', {
templateUrl: 'view-two.html',
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.when('/three', {
templateUrl: 'view-three.html',
controller: 'controllerThree',
controllerAs: 'ctrlThree'
})
.when('/three/:message', { // We will pass a param called 'message' with this route
templateUrl: 'view-three.html',
controller: 'controllerThree',
controllerAs: 'ctrlThree'
})
// redirect to here if no other routes match
.otherwise({
redirectTo: '/one'
});
});
Then, withoud making any changes in our templates, only adding a new link with custom
message, we can see the new custom message in our view.
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a href="#/one">View One</a>
<a href="#/two">View Two</a>
<a href="#/three">View Three</a>
<!-- New link with custom message -->
<a href="#/three/This-is-a-message">View Three with "This-is-a-message" custom message</a>
</nav>
<!-- views will be injected here -->
<div ng-view></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
https://riptutorial.com/ 196
</script>
The simplest manner of defining custom behavior for individual routes would be fairly easy.
1) routes.js: create a new property (like requireAuth) for any desired route
angular.module('yourApp').config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'templates/home.html',
requireAuth: true
})
.when('/login', {
templateUrl: 'templates/login.html',
})
.otherwise({
redirectTo: '/home'
});
}])
2) In a top-tier controller that isn't bound to an element inside the ng-view (to avoid conflict
with angular $routeProvider), check if the newUrl has the requireAuth property and act
accordingly
});
}
]);
https://riptutorial.com/ 197
Chapter 44: Services
Examples
How to create a Service
angular.module("app")
.service("counterService", function(){
var service = {
number: 0
};
return service;
});
angular.module("app")
// editable
<input ng-model="counter.number" />
or
// read-only
<span ng-bind="counter.number"></span>
Of course, in real code you would interact with the service using methods on the controller, which
in turn delegate to the service. The example above simply increments the counter value each time
the controller is used in a template.
Services are singleton objects that are instantiated only once per app (by the $injector) and lazy
loaded (created only when necessary).
A singleton is a class which only allows one instance of itself to be created - and gives
https://riptutorial.com/ 198
simple, easy access to said instance. As stated here
First define the service (in this case it uses the factory pattern):
.factory('dataService', function() {
var dataObject = {};
var service = {
// define the getter method
get data() {
return dataObject;
},
// define the setter method
set data(value) {
dataObject = value || {};
}
};
// return the "service" object to expose the getter/setter
return service;
})
Now you can use the service to share data between controllers:
.controller('controllerOne', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// create an object to store
var someObject = {
name: 'SomeObject',
value: 1
};
// store the object
this.dataService.data = someObject;
})
.controller('controllerTwo', function(dataService) {
// create a local reference to the dataService
this.dataService = dataService;
// this will automatically update with any changes to the shared data object
this.objectFromControllerOne = this.dataService.data;
})
injecting external sources and raw HTML into the template requires manual wrapping of$sce.
Demo
https://riptutorial.com/ 199
return function(content) {
return $sce.trustAsResourceUrl(content);
};
}]);
Usage in template
</div>
angular.module("app")
.service("counterService", ["fooService", "barService", function(anotherService,
barService){
var service = {
number: 0,
foo: function () {
return fooService.bazMethod(); // Use of 'fooService'
},
bar: function () {
return barService.bazMethod(); // Use of 'barService'
}
};
return service;
}]);
Registering a Service
The most common and flexible way to create a service uses the angular.module API factory:
The service factory function can be either a function or an array, just like the way we create
controllers:
https://riptutorial.com/ 200
To expose a method on our service, we can place it as an attribute on the service object.
angular.module('myApp.services', [])
.factory('githubService', function($http) {
var githubUrl = 'https://api.github.com';
var runUserRequest = function(username, path) {
// Return the promise from the $http service
// that calls the Github API using JSONP
return $http({
method: 'JSONP',
url: githubUrl + '/users/' +
username + '/' +
path + '?callback=JSON_CALLBACK'
});
}
// Return the service object with a single function
// events
return {
events: function(username) {
return runUserRequest(username, 'events');
}
};
1) Services
A service is a constructor function that is invoked once at runtime with new, just like what we would
do with plain javascript with only difference that AngularJs is calling the new behind the scenes.
Lets see a simple example where we would register a service which uses $http service to fetch
student details, and use it in the controller
function StudentDetailsService($http) {
this.getStudentDetails = function getStudentDetails() {
return $http.get('/details');
};
}
angular.module('myapp').service('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
When to use?
https://riptutorial.com/ 201
Use .service() wherever you want to use a constructor. It is usually used to create public API's
just like getStudentDetails(). But if you don't want to use a constructor and wish to use a simple
API pattern instead, then there isn't much flexibility in .service().
2) Factory
Even though we can achieve all the things using .factory() which we would, using .services(), it
doesn't make .factory() "same as" .service(). It is much more powerful and flexible than
.service()
Lets see an example where factory is used to return an object using a basic Revealing module
pattern
function StudentDetailsService($http) {
function getStudentDetails() {
return $http.get('/details');
}
return {
getStudentDetails: getStudentDetails
};
}
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
StudentDetailsService.getStudentDetails().then(function (response) {
// handle response
});
}
angular.module('app').controller('StudentController', StudentController);
Returning Closures
What is a closure?
Closures are functions that refer to variables that are used locally, BUT defined in an enclosing
scope.
https://riptutorial.com/ 202
function closureFunction(name) {
function innerClosureFunction(age) { // innerClosureFunction() is the inner function, a
closure
// Here you can manipulate 'age' AND 'name' variables both
};
};
The "wonderful" part is that it can access the name which is in the parent scope.
function StudentDetailsService($http) {
function closureFunction(name) {
function innerClosureFunction(age) {
// Here you can manipulate 'age' AND 'name' variables
};
};
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
var myClosure = StudentDetailsService('Student Name'); // This now HAS the
innerClosureFunction()
var callMyClosure = myClosure(24); // This calls the innerClosureFunction()
};
angular.module('app').controller('StudentController', StudentController);
Creating Constructors/instances
.service()creates constructors with a call to new as seen above. .factory() can also create
constructors with a call to new
function StudentDetailsService($http) {
function Student() {
this.age = function () {
return 'This is my age';
};
}
Student.prototype.address = function () {
return 'This is my address';
};
return Student;
};
angular.module('myapp').factory('StudentDetailsService', StudentDetailsService);
function StudentController(StudentDetailsService) {
https://riptutorial.com/ 203
var newStudent = new StudentDetailsService();
//Now the instance has been created. Its properties can be accessed.
newStudent.age();
newStudent.address();
};
angular.module('app').controller('StudentController', StudentController);
https://riptutorial.com/ 204
Chapter 45: Session storage
Examples
Handling session storage through service using angularjs
'use strict';
/**
* @ngdoc factory
* @name app.factory:storageService
* @description This function will communicate with HTML5 sessionStorage via Factory Service.
*/
return {
get: function(key) {
return sessionStorage.getItem(key);
},
save: function(key, data) {
sessionStorage.setItem(key, data);
}
};
}]);
In controller :
Inject the storageService dependency in the controller to set and get the data from the session
storage.
app.controller('myCtrl',['storageService',function(storageService) {
});
https://riptutorial.com/ 205
Chapter 46: Sharing Data
Remarks
A very common question when working with Angular is how to share data between controllers.
Using a service is the most frequent response and this is a simple example demonstrating a
factory pattern to share any type of data object between two or more controllers. Because it is a
shared object reference, an update in one controller will be immediately available in all other
controllers using the service. Note that both service and factory and both providers.
Examples
Using ngStorage to share data
<head>
<title>Angular JS ngStorage</title>
<script src =
"http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://rawgithub.com/gsklee/ngStorage/master/ngStorage.js"></script>
</head>
gives you 2 storage namely: $localStorage and $sessionStorage. You need to require
ngStorage
ngStorage and Inject the services.
$localStorage and $sessionStorage is globally accessible through any controllers as long as you
inject those services in the controllers.
You can also use the localStorage and sessionStorage of HTML5. However, using HTML5 localStorage
would require you to serialize and deserialize your objects before using or saving them.
https://riptutorial.com/ 206
For example:
var myObj = {
firstname: "Nic",
lastname: "Raboy",
website: "https://www.google.com"
}
//if you wanted to save into localStorage, serialize it
window.localStorage.set("saved", JSON.stringify(myObj));
We can create a service to set and get the data between the controllers and then inject that
service in the controller function where we want to use it.
Service :
app.service('setGetData', function() {
var data = '';
getData: function() { return data; },
setData: function(requestData) { data = requestData; }
});
Controllers :
app.controller('myCtrl1', ['setGetData',function(setGetData) {
}]);
app.controller('myCtrl2', ['setGetData',function(setGetData) {
}]);
Here, we can see that myCtrl1 is used for setting the data and myCtrl2 is used for getting the data.
So, we can share the data from one controller to another contrller like this.
https://riptutorial.com/ 207
Chapter 47: SignalR with AngularJs
Introduction
In this Article we focus on "How to create a simple project using AngularJs And SignalR", in this
training you need to know about "how create app with angularjs", "how to create/use service on
angular" And basic knowledge about SignalR" for this we recommend
https://www.codeproject.com/Tips/590660/Introduction-to-SignalR).
Examples
SignalR And AngularJs [ ChatProject ]
- Application
- app.js
- Controllers
- appController.js
- Factories
- SignalR-factory.js
- index.html
- Scripts
- angular.js
- jquery.js
- jquery.signalR.min.js
- Hubs
Startup.cs
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(SignalR.Hubs.Startup))]
namespace SignalR.Hubs
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}
https://riptutorial.com/ 208
ChatHub.cs
using Microsoft.AspNet.SignalR;
namespace SignalR.Hubs
{
public class ChatHub : Hub
{
public void Send(string name, string message, string time)
{
Clients.All.broadcastMessage(name, message, time);
}
}
}
app.js
SignalR-factory.js
app.factory("signalR", function () {
var factory = {};
factory.connectToHub = function () {
return $.connection[factory.hub];
}
factory.client = function () {
var hub = factory.connectToHub();
return hub.client;
}
factory.server = function () {
var hub = factory.connectToHub();
return hub.server;
}
https://riptutorial.com/ 209
return factory;
});
app.run(function(signalR) {
signalR.url("http://localhost:21991/signalr");
});
signalR.setHubName("chatHub");
$scope.$apply(function() {
$scope.messages.push(newChat);
});
};
signalR.start(function () {
$scope.send = function () {
var dt = new Date();
var time = dt.getHours() + ":" + dt.getMinutes() + ":" + dt.getSeconds();
Note: do not insert HubName with upper Case, first letter is lower Case.
signalR.client() | this method try to connect to your hubs and get all functions in the
Hubs, in this sample we have "chatHub", to get "broadcastMessage()" function;
index.html
<!DOCTYPE html>
<html ng-app="app" ng-controller="ctrl">
https://riptutorial.com/ 210
<head>
<meta charset="utf-8" />
<title>SignalR Simple Chat</title>
</head>
<body>
<form>
<input type="text" placeholder="name" ng-model="user.name" />
<input type="text" placeholder="message" ng-model="user.message" />
<button ng-click="send()">send</button>
<ul>
<li ng-repeat="item in messages">
<b ng-bind="item.name"></b> <small ng-bind="item.time"></small> :
{{item.message}}
</li>
</ul>
</form>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/jquery-1.6.4.min.js"></script>
<script src="Scripts/jquery.signalR-2.2.1.min.js"></script>
<script src="signalr/hubs"></script>
<script src="app.js"></script>
<script src="SignalR-factory.js"></script>
</body>
</html
https://riptutorial.com/ 211
Chapter 48: The Self Or This Variable In A
Controller
Introduction
This is an explanation of a common pattern and generally considered best practice that you may
see in AngularJS code.
Examples
Understanding The Purpose Of The Self Variable
When using "controller as syntax" you would give your controller an alias in the html when using
the ng-controller directive.
You can then access properties and methods from the main variable that represents our controller
instance. For example, let's access the greeting property of our controller and display it on the
screen:
Now, in our controller, we need to set a value to the greeting property of our controller instance (as
opposed to $scope or something else):
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
In order to have the HTML display correctly we needed to set the greeting property on this inside
of our controller body. I am creating an intermediate variable named self that holds a reference to
this. Why? Consider this code:
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
https://riptutorial.com/ 212
self.greeting = "Hello World";
function itsLate () {
this.greeting = "Goodnight";
}
})
In this above code you may expect the text on the screen to update when the method itsLate is
called, but in fact it does not. JavaScript uses function level scoping rules so the "this" inside of
itsLate refers to something different that "this" outside of the method body. However, we can get
the desired result if we use the self variable:
angular
.module('ngNjOrg')
.controller('ForgotPasswordController',function ($log) {
var self = this;
function itsLate () {
self.greeting = "Goodnight";
}
})
This is the beauty of using a "self" variable in your controllers- you can access this anywhere in
your controller and can always be sure that it is referencing your controller instance.
https://riptutorial.com/ 213
Chapter 49: ui-router
Remarks
What is ui-router?
Routing frameworks for SPAs update the browser's URL as the user navigates through
the app. Conversely, this allows changes to the browser's URL to drive navigation
through the app, thus allowing the user to create a bookmark to a location deep within
the SPA.
Useful links
You can find the official API Documentation here. For questions about ui-router VS ng-router, you
can find a reasonably detailed answer here. Keep in mind ng-router has already released a new
ng-router update called ngNewRouter (compatible with Angular 1.5+/2.0) which supports states just
like ui-router. You can read more about ngNewRouter here.
Examples
Basic Example
app.js
angular.module('myApp', ['ui.router'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('one', {
url: "/one",
templateUrl: "view-one.html",
controller: 'controllerOne',
controllerAs: 'ctrlOne'
})
.state('two', {
https://riptutorial.com/ 214
url: "/two",
templateUrl: "view-two.html",
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
})
.state('three', {
url: "/three",
templateUrl: "view-three.html",
controller: 'controllerThree',
controllerAs: 'ctrlThree'
});
$urlRouterProvider.otherwise('/one');
});
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a ui-sref="one">View One</a>
<a ui-sref="two">View Two</a>
<a ui-sref="three">View Three</a>
</nav>
<!-- views will be injected here -->
<div ui-view></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
Multiple Views
app.js
angular.module('myApp', ['ui.router'])
.controller('controllerOne', function() {
this.message = 'Hello world from Controller One!';
})
.controller('controllerTwo', function() {
this.message = 'Hello world from Controller Two!';
})
.controller('controllerThree', function() {
this.message = 'Hello world from Controller Three!';
})
.controller('controllerFour', function() {
this.message = 'Hello world from Controller Four!';
})
.config(function($stateProvider, $urlRouterProvider) {
https://riptutorial.com/ 215
$stateProvider
.state('one', {
url: "/one",
views: {
"viewA": {
templateUrl: "view-one.html",
controller: 'controllerOne',
controllerAs: 'ctrlOne'
},
"viewB": {
templateUrl: "view-two.html",
controller: 'controllerTwo',
controllerAs: 'ctrlTwo'
}
}
})
.state('two', {
url: "/two",
views: {
"viewA": {
templateUrl: "view-three.html",
controller: 'controllerThree',
controllerAs: 'ctrlThree'
},
"viewB": {
templateUrl: "view-four.html",
controller: 'controllerFour',
controllerAs: 'ctrlFour'
}
}
});
$urlRouterProvider.otherwise('/one');
});
index.html
<div ng-app="myApp">
<nav>
<!-- links to switch routes -->
<a ui-sref="one">Route One</a>
<a ui-sref="two">Route Two</a>
</nav>
<!-- views will be injected here -->
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
<!-- templates can live in normal html files -->
<script type="text/ng-template" id="view-one.html">
<h1>{{ctrlOne.message}}</h1>
</script>
https://riptutorial.com/ 216
<h1>{{ctrlFour.message}}</h1>
</script>
</div>
app.js
angular.module('myApp', ['ui.router'])
.service('User', ['$http', function User ($http) {
this.getProfile = function (id) {
return $http.get(...) // method to load data from API
};
}])
.controller('profileCtrl', ['profile', function profileCtrl (profile) {
// inject resolved data under the name of the resolve function
// data will already be returned and processed
this.profile = profile;
}])
.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider,
$urlRouterProvider) {
$stateProvider
.state('profile', {
url: "/profile/:userId",
templateUrl: "profile.html",
controller: 'profileCtrl',
controllerAs: 'vm',
resolve: {
profile: ['$stateParams', 'User', function ($stateParams, User) {
// $stateParams will contain any parameter defined in your url
return User.getProfile($stateParams.userId)
// .then is only necessary if you need to process returned data
.then(function (data) {
return doSomeProcessing(data);
});
}]
}
}]);
$urlRouterProvider.otherwise('/');
});
profile.html
<ul>
<li>Name: {{vm.profile.name}}</li>
<li>Age: {{vm.profile.age}}</li>
<li>Sex: {{vm.profile.sex}}</li>
</ul>
Resolve functions must be resolved before the $stateChangeSuccess event is fired, which means
that the UI will not load until all resolve functions on the state have finished. This is a great way to
ensure that data will be available to your controller and UI. However, you can see that a resolve
function should be fast in order to avoid hanging the UI.
https://riptutorial.com/ 217
Nested Views / States
app.js
app.config(function($stateProvider,$urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: function($scope){
$scope.text = 'This is the Home'
}
})
.state('home.nested1',{
url: '/nested1',
templateUrl:'nested1.html',
controller: function($scope){
$scope.text1 = 'This is the nested view 1'
}
})
.state('home.nested2',{
url: '/nested2',
templateUrl:'nested2.html',
controller: function($scope){
$scope.fruits = ['apple','mango','oranges'];
}
});
$urlRouterProvider.otherwise('/home');
});
index.html
<div ui-view></div>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="angular-ui-router.min.js"></script>
<script src="app.js"></script>
home.html
<div>
<h1> {{text}} </h1>
<br>
<a ui-sref="home.nested1">Show nested1</a>
<br>
<a ui-sref="home.nested2">Show nested2</a>
<br>
<div ui-view></div>
https://riptutorial.com/ 218
</div>
nested1.html
<div>
<h1> {{text1}} </h1>
</div>
nested2.html
<div>
<ul>
<li ng-repeat="fruit in fruits">{{ fruit }}</li>
</ul>
</div>
https://riptutorial.com/ 219
Chapter 50: Unit tests
Remarks
This topic provides examples for unit testing the various constructs in AngularJS. Unit tests are
often written using using Jasmine, a popular behavior driven testing framework. When unit testing
angular constructs, you will need to include ngMock as a dependency when running the unit tests.
Examples
Unit test a filter
Filter code:
The test:
describe('multiplierFilter', function() {
var filter;
beforeEach(function() {
module('myModule');
inject(function(multiplierFilter) {
filter = multiplierFilter;
});
});
https://riptutorial.com/ 220
});
Run!
Remark: In the inject call in the test, your filter needs to be specified by its name + Filter. The
cause for this is that whenever you register a filter for your module, Angular register it with a Filter
appended to its name.
Component code:
angular.module('myModule', []).component('myComponent', {
bindings: {
myValue: '<'
},
controller: function(MyService) {
this.service = MyService;
this.componentMethod = function() {
return 2;
};
}
});
The test:
describe('myComponent', function() {
var component;
beforeEach(function() {
module('myModule');
inject(function($componentController) {
// 1st - component name, 2nd - controller injections, 3rd - bindings
component = $componentController('myComponent', {
MyService: MyServiceFake
}, {
myValue: 3
});
});
});
Run!
https://riptutorial.com/ 221
Unit test a controller
Controller code:
angular.module('myModule', [])
.controller('myController', function($scope) {
$scope.num = 2;
$scope.doSomething = function() {
$scope.num += 2;
}
});
The test:
describe('myController', function() {
var $scope;
beforeEach(function() {
module('myModule');
inject(function($controller, $rootScope) {
$scope = $rootScope.$new();
$controller('myController', {
'$scope': $scope
})
});
});
it('should increment `num` by 2', function() {
expect($scope.num).toEqual(2);
$scope.doSomething();
expect($scope.num).toEqual(4);
});
});
Run!
Service Code
angular.module('myModule', [])
.service('myService', function() {
this.doSomething = function(someNumber) {
return someNumber + 2;
}
});
The test
describe('myService', function() {
var myService;
beforeEach(function() {
module('myModule');
inject(function(_myService_) {
myService = _myService_;
});
});
https://riptutorial.com/ 222
it('should increment `num` by 2', function() {
var result = myService.doSomething(4);
expect(result).toEqual(6);
});
});
Run!
Directive code
angular.module('myModule', [])
.directive('myDirective', function() {
return {
template: '<div>{{greeting}} {{name}}!</div>',
scope: {
name: '=',
greeting: '@'
}
};
});
The test
describe('myDirective', function() {
var element, scope;
beforeEach(function() {
module('myModule');
inject(function($compile, $rootScope) {
scope = $rootScope.$new();
element = angular.element("<my-directive name='name' greeting='Hello'></my-directive>");
$compile(element)(scope);
/* PLEASE NEVER USE scope.$digest(). scope.$apply use a protection to avoid to run a
digest loop when there is already one, so, use scope.$apply() instead. */
scope.$apply();
})
});
Run!
https://riptutorial.com/ 223
Read Unit tests online: https://riptutorial.com/angularjs/topic/1689/unit-tests
https://riptutorial.com/ 224
Chapter 51: Use of in-built directives
Examples
Hide/Show HTML Elements
<!DOCTYPE html>
<html ng-app="myDemoApp">
<head>
<script src="https://code.angularjs.org/1.5.8/angular.min.js"></script>
<script>
function HideShowController() {
var vm = this;
vm.show=false;
vm.toggle= function() {
vm.show=!vm.show;
}
}
Live Demo
1. ng-app="myDemoApp", the ngApp directive tells angular that a DOM element is controlled by a
specific angular.module named "myDemoApp".
2. <script src="[//angular include]"> include angular js.
3. HideShowController function is defined containing another function named toggle which help
to hide show the element.
4. angular.module(...) creates a new module.
5. .controller(...) Angular Controller and returns the module for chaining;
6. ng-controller directive is key aspect of how angular supports the principles behind the
Model-View-Controller design pattern.
7. ng-show directive shows the given HTML element if expression provided is true.
8. ng-hide directive hides the given HTML element if expression provided is true.
9. ng-click directive fires a toggle function inside controller
https://riptutorial.com/ 225
Read Use of in-built directives online: https://riptutorial.com/angularjs/topic/7644/use-of-in-built-
directives
https://riptutorial.com/ 226
Chapter 52: Using AngularJS with TypeScript
Syntax
• $scope : ng.IScope - this is way in typescript to define type for a particular variable.
Examples
Angular Controllers in Typescript
When a Controller is attached to the DOM via the ng-controller directive, Angular will
instantiate a new Controller object, using the specified Controller's constructor function.
A new child scope will be created and made available as an injectable parameter to the
Controller's constructor function as $scope.
module App.Controllers {
class Address {
line1: string;
line2: string;
city: string;
state: string;
}
export class SampleController {
firstName: string;
lastName: string;
age: number;
address: Address;
setUpWatches($scope: ng.IScope): void {
$scope.$watch(() => this.firstName, (n, o) => {
//n is string and so is o
});
};
constructor($scope: ng.IScope) {
this.setUpWatches($scope);
}
}
}
var App;
(function (App) {
var Controllers;
(function (Controllers) {
var Address = (function () {
function Address() {
}
https://riptutorial.com/ 227
return Address;
}());
var SampleController = (function () {
function SampleController($scope) {
this.setUpWatches($scope);
}
SampleController.prototype.setUpWatches = function ($scope) {
var _this = this;
$scope.$watch(function () { return _this.firstName; }, function (n, o) {
//n is string and so is o
});
};
;
return SampleController;
}());
Controllers.SampleController = SampleController;
})(Controllers = App.Controllers || (App.Controllers = {}));
})(App || (App = {}));
//# sourceMappingURL=ExampleController.js.map
After making the controller class let the angular js module about the controller can be done simple
by using the class
app
.module('app')
.controller('exampleController', App.Controller.SampleController)
The Controller we have made can be instantiated and used using controller as Syntax. That's
because we have put variable directly on the controller class and not on the $scope.
Using controller as someName is to seperate the controller from $scope itself.So, there is no need of
injecting $scope as the dependency in the controller.
Traditional way :
<div ng-controller="MyCtrl">
{{name}}
</div>
https://riptutorial.com/ 228
</div>
So, now we can use jsObj instance to access any method or property of jsClass.
The way the $scope is injected in the controller's constructor functions is a way to demonstrate
and use the basic option of angular dependency injection but is not production ready as it cannot
be minified. Thats because the minification system changes the variable names and anguar's
dependency injection uses the parameter names to know what has to be injected. So for an
example the ExampleController's constructor function is minified to the following code.
function n(n){this.setUpWatches(n)
module App.Controllers {
class Address {
line1: string;
line2: string;
city: string;
state: string;
}
export class SampleController {
firstName: string;
lastName: string;
age: number;
address: Address;
setUpWatches($scope: ng.IScope): void {
$scope.$watch(() => this.firstName, (n, o) => {
//n is string and so is o
});
};
static $inject : string[] = ['$scope'];
constructor($scope: ng.IScope) {
this.setUpWatches($scope);
}
}
}
https://riptutorial.com/ 229
Why ControllerAs Syntax ?
Controller Function
Controller function is nothing but just a JavaScript constructor function. Hence, when a view loads
the function context(this) is set to the controller object.
Case 1 :
It is created in the controller object, not on $scope. views can not access the functions defined on
controller object.
Example :
Case 2 :
It is created in the $scope object, not on controller object. views can only access the functions
defined on $scope object.
Example :
Why ControllerAs ?
• ControllerAs syntax makes it much clearer where objects are being manipulated.Having
oneCtrl.name and anotherCtrl.name makes it much easier to identify that you have an name
assigned by multiple different controllers for different purposes but if both used same
$scope.name and having two different HTML elements on a page which both are bound to
{{name}} then it is difficult to identify which one is from which controller.
• Hiding the $scope and exposing the members from the controller to the view via an
intermediary object. By setting this.*, we can expose just what we want to expose from the
controller to the view.
<div ng-controller="FirstCtrl">
{{ name }}
<div ng-controller="SecondCtrl">
{{ name }}
https://riptutorial.com/ 230
<div ng-controller="ThirdCtrl">
{{ name }}
</div>
</div>
</div>
Here, in above case {{ name }} will be very confusing to use and We also don't know which one
related to which controller.
Why $scope ?
• Use $scope when you need to access one or more methods of $scope such as $watch,
$digest, $emit, $http etc.
• limit which properties and/or methods are exposed to $scope, then explicitly passing them to
$scope as needed.
https://riptutorial.com/ 231
Credits
S.
Chapters Contributors
No
Angular Project -
5 jitender, Liron Ilayev
Directory Structure
AngularJS bindings
7 options (`=`, `@`, `&` Alon Eitan, Lucas L, Makarov Sergey, Nico, zucker
etc.)
https://riptutorial.com/ 232
redunderthebed, Richard Hamilton, svarog, tanmay,
theblindprophet, timbo, Tomislav Stankovic, vincentvanjoe,
Vishal Singh
Built-in helper
11 MoLow, Pranav C Balan, svarog
Functions
13 Constants Sylvain
digest loop
22 Alon Eitan, chris, MoLow, prit4fun
walkthrough
Directives using
23 Nikos Paraskevopoulos
ngModelController
Distinguishing
24 Deepak Bansal
Service vs Factory
https://riptutorial.com/ 233
Aeolingamenfel, developer033, Ed Hinchliffe, fracz,
26 Filters
gustavohenke, Matthew Green, Nico
Migration to Angular
32 ShinDarth
2+
Performance
38 Deepak Bansal
Profiling
Prepare for
39 JanisP
Production - Grunt
40 Print ziaulain
https://riptutorial.com/ 234
Abdellah Alaoui, Alvaro Vazquez, AnonDCX, DotBot, elliot-j,
44 Services Flash, Gavishiddappa Gadagi, Hubert Grzeskowiak, Lex,
Nishant123
SignalR with
47 Maher
AngularJs
Use of in-built
51 Gourav Garg
directives
Using AngularJS
52 Parv Sharma, Rohit Jindal
with TypeScript
https://riptutorial.com/ 235