Powered By Blogger

Wednesday, July 15, 2015

$parse and $eval [Angular]

$parse and $eval both operate on angular expressions i.e. {{ expression }}.

$eval is a scope method which executes an expression on the current scope and returns the result.
 scope.a = 1;   
 scope.b = 2;   
 scope.$eval('a+b'); // 3  
$parse is an Angular service which converts an expression into a function. Then function can be invoked and passed a context (usually scope) in order to retrieve the expression's value.
 <div my-attr="obj.name" my-directive> theprogrammingtree.com </div>   
 <script type="text/javascript">   
 myApp.directive('myDirective', function( $parse, $log ) {   
    return function( scope, el, attrs ) {  
      // parse the "my-attr" attribute value into a function   
      var myFn = $parse( attrs.myAttr );   
      // "myFn" is now a function which can be invoked to get the expression's value;   
      // the following line logs the value of obj.name on scope:   
       $log.log(myFn(scope) );   
      // theprogrammingtree.com   
      el.bind('click', function() {   
        // "myFn.assign" is also a function; it can be invoked to   
        // update the expresssion value   
        myFn.assign(scope, "New name");   
        scope.$apply();   
      })   
    }   
 });   
 </script>  
Also, if the expression is assignable then the returned function will have an assign property. The assign property is a function that can be used to change the expression's value on the given context.

digest life-cycle in AngularJS

The digest loop is responsible to update DOM elements with the changes made to the model as well as executing any registered watcher functions.

The $digest loop is fired when the browser receives an event that can be managed by the angular context. This loop is made up of two smaller loops. One processes the $evalAsync queue and the other one processes the $watch list.

The $digest loop keeps iterating until the $evalAsync queue is empty and the $watch list does not detect any changes in the model.

The $evalAsync queue contains those tasks which are scheduled by $evalAsync() function from a directive or controller.

The $watch list contains watches correspondence to each DOM element which is bound to the $scope object. These watches are resolved in the $digest loop through a process called dirty checking. The dirty checking is a process which checks whether a value has changed, if the value has changed, it set the $scope as dirty. If the $scope is dirty, another $digest loop is triggered.

When you do the changes to the scope outside the angular context, you have to call $apply() function explicitly on the scope to trigger $digest cycle immediately.

$evalAsync - This executes the expression on the current scope on later time. The $evalAsync makes no guarantees as to when the expression will be executed, only that:

1. If code is queued using $evalAsync from a directive, it will run after the DOM has been manipulated by Angular, but before the browser renders.

2. If code is queued using $evalAsync from a controller, it will run before the DOM has been manipulated by Angular and before the browser renders.

scope life-cycle [Angular]

Scope data goes through a life cycle when the angular app is loaded into the browser. Understanding the scope life cycle will help you to understand the interaction between scope and other AngularJS components.

The scope data goes through the following life cycle phases:

1. Creation – This phase initialized the scope. The root scope is created by the $injector when the application is bootstrapped. During template linking, some directives create new child scopes.
A digest loop is also created in this phase that interacts with the browser event loop. This digest loop is responsible to update DOM elements with the changes made to the model as well as executing any registered watcher functions.

2. Watcher registration - This phase registers watches for values on the scope that are represented in the template. These watches propagate model changes automatically to the DOM elements.
You can also register your own watch functions on a scope value by using the $watch() function.

3. Model mutation - This phase occurs when data in the scope changes. When you make the changes in your angular app code, the scope function $apply() updates the model and calls the $digest() function to update the DOM elements and registered watches.

When you do the changes to scope inside your angular code like within controllers or services, angular internally call $apply() function for you. But when you do the changes to the scope outside the angular code, you have to call $apply() function explicitly on the scope to force the model and DOM to be updated correctly.

4. Mutation observation – This phase occurs when the $digest() function is executed by the digest loop at the end of $apply() call. When $digest() function executes, it evaluates all watches for model changes. If a value has been changed, $digest() calls the $watch listener and updates the DOM elements.

5. Scope destruction – This phase occurs when child scopes are no longer needed and these scopes are removed from the browser’s memory by using $destroy() function. It is the responsibility of the child scope creator to destroy them via scope.$destroy() API.
This stop propagation of $digest calls into the child scopes and allow the memory to be reclaimed by the browser garbage collector.

$watch(), $watchgroup() and $watchCollection() [Angular]

$watch - This function is used to observe changes in a variable on the $scope. It accepts three parameters: expression, listener and equality object, where listener and equality object are optional parameters.
 $watch(watchExpression, listener, [objectEquality])  
Here, watchExpression is the expression in the scope to watch. This expression is called on every $digest() and returns the value that is being watched.

The listener defines a function that is called when the value of the watchExpression changes to a new value. If the watchExpression is not changed then listener will not be called.
The objectEquality is a boolean type which is used for comparing the objects for equality using angular.equals instead of comparing for reference equality.
 scope.name = 'pratik';   
 scope.counter = 0;   
 scope.$watch('name', function (newVal, oldVal) {   
     scope.counter = scope.counter + 1;   
 });  

$watchgroup - This function is introduced in Angular1.3. This works the same as $watch() function except that the first parameter is an array of expressions to watch.
 $watchGroup(watchExpression, listener)  
The listener is passed as an array with the new and old values for the watched variables. The listener is called whenever any expression in the watchExpressions array changes.
 $scope.teamScore = 0;   
 $scope.time = 0;   
 $scope.$watchGroup(['teamScore', 'time'], function(newVal, oldVal) {  
      if(newVal[0] > 20){   
       $scope.matchStatus = 'win';   
      } else if (newVal[1] > 60){   
       $scope.matchStatus = 'times up';   
      }  
 });  
$watchCollection - This function is used to watch the properties of an object and fires whenever any of the properties change. It takes an object as the first parameter and watches the properties of the object.
 $watchCollection(obj, listener)  
The listener is called whenever anything within the obj has been changed.
 $scope.names = ['t1', 't2', 't3','t4'];   
 $scope.dataCount = 4;   
 $scope.$watchCollection('names', function (newVal, oldVal) {   
    $scope.dataCount = newVal.length;   
 });  

$watch, $digest and $apply [Angular]

$watch() - This function is used to observe changes in a variable on the $scope. It accepts three parameters: expression, listener and equality object, where listener and equality object are optional parameters.
$watch(watchExpression, listener, [objectEquality]);
 <html>   
 <head>   
 <title>AngularJS Watch</title>  
 <script src="lib/angular.js"></script>   
 <script>   
 var myapp = angular.module("myapp", []);   
 var myController = myapp.controller("myController", function ($scope) {   
     $scope.name = 'theprogrammingtree.com';   
     $scope.counter = 0;   
    //watching change in name value   
    $scope.$watch('name', function (newValue, oldValue) {   
        $scope.counter = $scope.counter + 1;   
    });   
 });   
 </script>   
 </head>   
 <body ng-app="myapp" ng-controller="myController">   
 <input type="text" ng-model="name" /> <br /><br />   
 Counter: {{counter}}   
 </body>   
 </html>  

$digest() - This function iterates through all the watches in the $scope object, and its child $scope objects (if it has any). When $digest() iterates over the watches, it checks if the value of the expression has changed. If the value has changed, AngularJS calls the listener with the new value and the old value.

The $digest() function is called whenever AngularJS thinks it is necessary. For example, after a button click, or after an AJAX call. You may have some cases where AngularJS does not call the $digest() function for you. In that case you have to call it yourself.

 <html>   
 <head>   
 <script src="lib/jquery-1.11.1.js"></script>   
 <script src="lib/angular.js"></script>   
 </head>   
 <body ng-app="app">   
 <div ng-controller="Ctrl">   
   <button class="digest">Digest my scope!</button> <br />   
   <h2>obj value : {{obj.value}}</h2>   
 </div>   
 <script>   
 var app = angular.module('app', []);   
 app.controller('Ctrl', function ($scope) {   
     $scope.obj = { value: 1 };   
     $('.digest').click(function () {   
       console.log("digest clicked!");   
       console.log($scope.obj.value++);   
      //update value   
      $scope.$digest();  
     });   
 });   
 </script>   
 </body>   
 </html>  

$apply() - Angular do auto-magically updates only those model changes which are inside AngularJS context. When you do change in any model outside of the Angular context (like browser DOM events, setTimeout, XHR or third party libraries), then you need to inform Angular of the changes by calling $apply() manually. When the $apply() function call finishes AngularJS calls $digest() internally, so all data bindings are updated.

 <html>   
 <head>   
 <title>AngularJS Apply</title>   
 <script src="lib/angular.js"></script>   
 <script>   
 var myapp = angular.module("myapp", []);   
 var myController = myapp.controller("myController", function ($scope) {   
    $scope.datetime = new Date();   
    $scope.updateTime = function () {   
      $scope.datetime = new Date();   
    }   
    //outside angular context  
    document.getElementById("updateTimeButton").addEventListener('click', function (){  
      //update the value   
      $scope.$apply(function () {   
       console.log("update time clicked");     
       $scope.datetime = new Date();   
       console.log($scope.datetime);   
     });   
    });   
 });   
 </script>   
 </head>   
 <body ng-app="myapp" ng-controller="myController">   
 <button ng-click="updateTime()">Update time - ng-click</button>   
 <button id="updateTimeButton">Update time</button> <br />   
 {{datetime | date:'yyyy-MM-dd HH:mm:ss'}}   
 </body>   
 </html>  

$digest() is faster than $apply(), since $apply() triggers watchers on the entire scope chain i.e. on the current scope and its parents or children (if it has) while $digest() triggers watchers on the current scope and its children(if it has).

When error occurs in one of the watchers, $digest() cannot handled errors via $exceptionHandler service, In this case you have to handle exception yourself.
While $apply() uses try catch block internally to handle errors and if error occurs in one of the watchers then it passes errors to $exceptionHandler service.

Pseudo-code for $apply()
 function $apply(expr) {  
    try {   
       return $eval(expr);   
    } catch (e) {   
       $exceptionHandler(e);   
    } finally {   
       $root.$digest();   
    }   
 }  

Data Binding Concept [Angular]

AngularJS data-binding is the most useful feature which saves you from writing boilerplate code (i.e. the sections of code which is included in many places with little or no alteration). Now, developers are not responsible for manually manipulating the DOM elements and attributes to reflect model changes. AngularJS provides two-way data-binding to handle the synchronization of data between model and view.

Two-way data binding - It is used to synchronize the data between model and view. It means, any change in model will update the view and vice versa. ng-model directive is used for two-way data binding.



One-way data binding - This binding is introduced in Angular 1.3. An expression that starts with double colon (::), is considered a one-time expression i.e. one-way binding.


Two-Way and One-Way data binding Example
 <div ng-controller="MyCtrl">   
 <label>Name (two-way binding): <input type="text" ng-model="name" /></label>   
 <strong>Your name (one-way binding):</strong> {{::name}}<br />   
 <strong>Your name (normal binding):</strong> {{name}} </div>   
 <script>   
 var app = angular.module('app', []);   
 app.controller("MyCtrl", function ($scope) {   
    $scope.name = "Pratik Panchal"   
 })   
 </script>  

Why one-way data binding is introduced?

In order to make data-binding possible, Angular uses $watch APIs to observe model changes on the scope. Angular registered watchers for each variable on scope to observe the change in its value. If the value, of variable on scope is changed then the view gets updated automatically.

This automatic change happens because of $digest cycle is triggered. Hence, Angular processes all registered watchers on the current scope and its children and checks for model changes and calls dedicated watch listeners until the model is stabilized and no more listeners are fired. Once the $digest loop finishes the execution, the browser re-renders the DOM and reflects the changes.

By default, every variable on a scope is observed by the angular. In this way, unnecessary variable are also observed by the angular that is time consuming and as a result page is becoming slow.
Hence to avoid unnecessary observing of variables on scope object, angular introduced one-way data binding.

How AngularJS handle data binding?

AngularJS handle data-binding mechanism with the help of three powerful functions: $watch(), $digest() and $apply(). Most of the time AngularJS will call the $scope.$watch() and $scope.$digest() functions for you, but in some cases you may have to call these functions yourself to update new values.

Angular Compilation

Angular's HTML compiler allows you to teach the browser new HTML syntax. The compiler allows you to attach new behaviors or attributes to any HTML element. Angular calls these behaviors as directives.

AngularJS compilation process takes place in the web browser; no server side or pre-compilation step is involved. Angular uses $compiler service to compile your angular HTML page. The angular' compilation process begins after your HTML page (static DOM) is fully loaded. It happens in two phases:

Compile - It traverse the DOM and collect all of the directives. The result is a linking function.

Link - It combines the directives with a scope and produces a live view. Any changes in the scope model are reflected in the view, and any user interactions with the view are reflected in the scope model.

The concept of compile and link comes from C language, where you first compile the code and then link it to actually execute it. The process is very much similar in AngularJS as well.

If you have worked on templates in other java script framework/library like backbone and jQuery, they process the template as a string and result as a string. You have to dumped this result string into the DOM where you wanted it with innerHTML()

AngularJS process the template in another way. It directly works on HTML DOM rather than strings and manipulates it as required. It uses two way data-binding between model and view to sync your data.

It is important to note that Angular operates on DOM nodes rather than strings. Usually, you don't notice this because when an html page loads, the web browser parses HTML into the DOM automatically.

HTML compilation happens in three phases:

1. The $compile traverses the DOM and looks for directives. For each directive it finds, it adds it to a list of directives.

2. Once the entire DOM has been traversed, it will sort that list of directives by their priority. Then, each directive’s own compile function is executed, giving each directive the chance to modify the DOM itself. Each compile function returns a linking function, which is then composed into a combined linking function and returned.

3. $compile links the template with the scope by calling the combined linking function from the previous step. This in turn will call the linking function of the individual directives, registering listeners on the elements and setting up $watch with the scope as each directive is configured to do.

The pseudo code for the above process is given below:

 var $compile = ...;   
 // injected into your code   
 var scope = ...;   
 var parent = ...;   
 // DOM element where the compiled template can be appended   
 var html = '<div ng-bind="exp"></div>';   
 // Step 1: parse HTML into DOM element   
 var template = angular.element(html);   
 // Step 2: compile the template   
 var linkFn = $compile(template);   
 // Step 3: link the compiled template with the scope.   
 var element = linkFn(scope);   
 // Step 4: Append to DOM (optional)   
 parent.appendChild(element);  

What are Compile, Pre, and Post linking in AngularJS?

Compile – This compiles an HTML string or DOM into a template and produces a template function, which can then be used to link scope and the template together.

Use the compile function to change the original DOM (template element) before AngularJS creates an instance of it and before a scope is created.


Post-Link – This is executed after the child elements are linked. It is safe to do DOM transformation in the post-linking function.
Use the post-link function to execute logic, knowing that all child elements have been compiled and all pre-link and post-link functions of child elements have been executed.

Pre-Link – This is executed before the child elements are linked. Not safe to do DOM transformation since the compiler linking function will fail to locate the correct elements for linking.
Use the pre-link function to implement logic that runs when AngularJS has already compiled the child elements, but before any of the child element's post-link functions have been called.

 <html>   
 <head>   
 <title>Compile vs Link</title>   
 <script src="lib/angular.js"></script>   
 <script type="text/javascript">   
 var app = angular.module('app', []);   
 function createDirective(name) {   
   return function () {   
    return {   
       restrict: 'E',   
       compile: function (tElem, tAttrs) {   
          console.log(name + ': compile');   
          return {   
            pre: function (scope, iElem, attrs) {   
              console.log(name + ': pre link');   
            },  
            post: function (scope, iElem, attrs) {   
              console.log(name + ': post link');   
            }  
          }  
        }   
     }   
    }   
 }   
 app.directive('levelOne', createDirective('level-One'));   
 app.directive('levelTwo', createDirective('level-Two'));   
 app.directive('levelThree', createDirective('level-Three'));   
 </script>   
 </head>   
 <body ng-app="app">   
 <level-one>   
   <level-two>   
     <level-three> Hello {{name}} </level-three>   
  </level-two>   
 </level-one>   
 </body>   
 </html>  

Output


Auto bootstrap vs Manual bootstrap process in Angular

Auto bootstrap

Angular initializes automatically upon DOMContentLoaded event or when the angular.js script is downloaded to the browser and the document.readyState is set to complete. At this point AngularJS looks for the ng-app directive which is the root of angular app compilation and tells about AngularJS part within DOM. When the ng-app directive is found then Angular will:

  1. Load the module associated with the directive.
  2. Create the application injector.
  3. Compile the DOM starting from the ng-app root element.
This process is called auto-bootstrapping.

 <html>   
 <body ng-app="myApp">   
 <div ng-controller="Ctrl"> Hello {{msg}}! </div>   
 <script src="lib/angular.js"></script>   
   
 <script>   
 var app = angular.module('myApp', []);   
 app.controller('Ctrl', function ($scope) {   
   $scope.msg = 'World';   
 });   
 </script>   
 </body>   
 </html>  


Manual Bootstrap

You can manually initialized your angular app by using angular.bootstrap() function. This function takes the modules as parameters and should be called within angular.element(document).ready() function. The angular.element(document).ready() function is fired when the DOM is ready for manipulation.


 <html>   
 <body>   
 <div ng-controller="Ctrl"> Hello {{msg}}! </div>   
 <script src="lib/angular.js"></script>   
   
 <script>   
 var app = angular.module('myApp', []);   
 app.controller('Ctrl', function ($scope) {   
   $scope.msg = 'World';   
 });   
   
 //manual bootstrap process   
 angular.element(document).ready(function () {   
   angular.bootstrap(document, ['myApp']);   
 });   
 </script>   
 </body>   
 </html>  


Note

  • You should not use the ng-app directive when manually bootstrapping your app.
  • You should not mix up the automatic and manual way of bootstrapping your app. 
  • Define modules, controller, services etc. before manually bootstrapping your app as defined in above example.

Tuesday, July 14, 2015

[Angular] Exploring Modules, Dependencies and Global APIs

ng is the core module in angular. This module is loaded by default when an angular app is started. This module provides the essential components for your angular app like directives, services/factories, filters, global APIs and testing components.

How angular modules load the dependencies?

An angular module use configuration and run blocks to inject dependencies (like providers, services and constants) which get applied to the angular app during the bootstrap process.

Configuration block – This block is executed during the provider registration and configuration phase. Only providers and constants can be injected into configuration blocks. This block is used to inject module wise configuration settings to prevent accidental instantiation of services before they have been fully configured. This block is created using config() method.

 angular.module('myModule', [])  
 . config(function (injectables) {   
   
 // provider-injector   
 // This is an example of config block.   
 // You can have as many of these as you want.   
 // You can only inject Providers (not instances)   
 // into config blocks.   
   
 }). run(function (injectables) {   
   
 // instance-injector   
 // This is an example of a run block.   
 // You can have as many of these as you want.   
 // You can only inject instances (not Providers)   
 // into run blocks   
   
 });  

Run block – This block is executed after the configuration block. It is used to inject instances and constants. This block is created using run() method. This method is like as main method in C or C++.
The run block is a great place to put event handlers that need to be executed at the root level for the application. For example, authentication handlers.

When dependent modules of a module are loaded?

A module might have dependencies on other modules. The dependent modules are loaded by angular before the requiring module is loaded.

In other words the configuration blocks of the dependent modules execute before the configuration blocks of the requiring module. The same is true for the run blocks. Each module can only be loaded once, even if multiple other modules require it.

What is Global API?

Global API provides you global functions to perform common JavaScript tasks such as comparing objects, deep copying, iterating through objects, and converting JSON data etc. All global functions can be accessed by using the angular object.

The list of global functions is given below:




Angular Introduction

AngularJS modules are containers just like namespace in C#. They divide an angular app into small, reusable and functional components which can be integrated with other angular app. Each module is identified by a unique name and can be dependent on other modules. In AngularJS, every web page (view) can have a single module assigned to it via ng-app directive.

Creating an Angular JS module

 // defining module   
 angular.module('myApp', []);   
   
 //defining module which has dependency on other modules   
 angular.module('myApp', ['dependentModule1', 'dependentModule2']);  

Using an AngularJS module into your app

You can bootstrap your app by using your AngularJS module as given below:

 <html ng-app="myApp">   
 <head> ... </head>   
 <body> ... </body>  
   

You can define following components with in your angular module:



Angular at the Root

By default AngularJS use jQLite which is the subset of jQuery. If you want to use jQuery then simply load the jQuery library before loading the AngularJS. By doing so, Angular will skip jQLite and will start to use jQuery library.


jQLite is a subset of jQuery that is built directly into AngularJS. jQLite provides you all the useful features of jQuery. In fact it provides you limited features or functions of jQuery.

jQuery lite or the full jQuery library if available, can be accessed via the AngularJS code by using the element() function in AngularJS. Basically, angular.element() is an alias for the jQuery function.

AngularJS is a first class JavaScript framework which allows you to build well structured, easily testable, and maintainable front-end applications. It is not a library since library provides you limited functionality or has dependencies to other libraries.
It is not a plugin or browser extension since it is based on JavaScript and compatible with both desktop and mobile browsers.

The features of AngularJS are listed below:

  • Modules
  • Directives
  • Templates
  • Scope
  • Expressions
  • Data Binding
  • MVC (Model, View & Controller)
  • Validations
  • Filters
  • Services
  • Routing
  • Dependency Injection
  • Testing

AngularJS provide following built-in protection from basic security holes:
  • Prevent HTML injection attacks.
  • Prevent Cross-Site-Scripting (CSS) attacks.
  • Provide XSRF protection for server side communication.
Also, AngularJS is designed to be compatible with other security measures like Content Security Policy (CSP), HTTPS (SSL/TLS) and server-side authentication and authorization that greatly reduce the possible attacks.

Getting started with Angular Java script.

AngularJS is an open-source JavaScript framework developed by Google. It helps you to create single-page applications or one-page web applications that only require HTML, CSS, and JavaScript on the client side. It is based on MV-* pattern and allow you to build well structured, easily testable, and maintainable front-end applications.



AngularJS has changed the way to web development. It is not based on jQuery to perform its operations. In spite of using JAVA Web form, JAVA MVC, PHP, JSP, Ruby on Rails for web development, you can do your complete web development by using most powerful and adaptive JavaScript Framework AngularJS. There is no doubt, JavaScript frameworks like AngularJS, Ember etc. are the future of web development.

There are following reasons to choose AngularJS as a web development framework:

  1. It is based on MVC pattern which helps you to organize your web apps or web application properly.
  2. It extends HTML by attaching directives to your HTML markup with new attributes or tags and expressions in order to define very powerful templates.
  3. It also allows you to create your own directives, making reusable components that fill your needs and abstract your DOM manipulation logic.
  4. It supports two-way data binding i.e. connects your HTML (views) to your JavaScript objects (models) seamlessly. In this way any change in model will update the view and vice versa without any DOM manipulation or event handling.
  5. It encapsulates the behaviour of your application in controllers which are instantiated with the help of dependency injection.
  6. It supports services that can be injected into your controllers to use some utility code to fulfil your need. For example, it provides $http service to communicate with REST service.
  7. It supports dependency injection which helps you to test your angular app code very easily.
  8. Also, AngularJS is mature community to help you. It has widely support over the internet.

There are following advantages of AngularJS:

Data Binding - AngularJS provides a powerful data binding mechanism to bind data to HTML elements by using scope.

Customize & Extensible - AngularJS is customized and extensible as per you requirement. You can create your own custom components like directives, services etc.

Code Reusability - AngularJS allows you to write code which can be reused. For example custom directive which you can reuse.

Support – AngularJS is mature community to help you. It has widely support over the internet. Also, AngularJS is supported by Google which gives it an advantage.

Compatibility - AngularJS is based on JavaScript which makes it easier to integrate with any other JavaScript library and runnable on browsers like IE, Opera, FF, Safari, Chrome etc.

Testing - AngularJS is designed to be testable so that you can test your AngularJS app components as easy as possible. It has dependency injection at its core, which makes it easy to test.

Today, AngularJS is the most popular and dominant JavaScript framework for professional web development. It is well suited for small, large and any sized web app and web application.
AngularJS is different from other JavaScript framework in following ways:

  • AngularJS mark-up lives in the DOM.
  • AngularJS uses plain old JavaScript objects (POJO).
  • AngularJS is leverages with Dependency Injection.