pipeline of ngModelController

ngModelController is undoubtedly one of the reasons why AngularJS is so awesome . It is responsible for two way data binding , which is what people use when they are asked to display Angular powers. It is the eye candy of Angular .

Yaa i sound like i am in love with it .. Well, yes i am.

Using ngModelController in its usual form ( inside input fields with ng-model) is all easy and fun. All you have to do is give a model value to ng-model attribute and you are good to go..

<div ng-controller="databinding">
<input type="text" ng-model="user" >
</div>
 
.controller('databinding',function($scope){
$scope.user="HiEveryone";
});
And there you have a two way data binding . But the heart pounding situation comes when you want to implement two way data binding on other tags or your custom directive . Yes it looks very complicated at first but once you understand the flow , you get all sorted.
So, what really is the flow .. The flow is :
Model->View

$modelValue->$formatters->$viewValue->$render

View->Model

$setViewValue->$viewValue->$parsers->$modelValue

 These names are methods and properties of ngModelController which you need to take hold of when creating your own custom two way data binding . To access ngModelController, you have to require ngModel , and you will have access to the controller as the fourth parameter in the link function.  
Suppose you have a custom directive with an ngmodel attribute :

<customdirective ng-model="bindvariable"></customdirective>

The directive definition will be :

.directive('customdirective',function(){
return {
require:'ngModel',
link: function(scope,element,attributes,ngModelController)
{
};
};
})
Now,
$modelValue - It is the value in the model , it retrives the value which is in the model.

$viewValue -   Actual string value in the view as given in Angular docs. But it sounds rather confusing to me becuase in your custom directive, unless you do a render, the value is not updated in the view . Yes, i know that obviously you will do render , but what if you give something else to render , like in this code .
Here, in the console, you can see that $viewValue is different and the value displayed in the view is different .

$render- It is called when the view needs to be updated, and yes you have to define a $render, else your view will not be rendered. 

$parsers- As explained in docs , $parsers accept an Array of functions to execute, as a pipeline, whenever the control reads value from the DOM. The functions are called in array order, each passing its return value through to the next. The last return value is forwarded to the $validators collection.
Parsers are used to sanitize / convert $viewValue .
$formatters :  As explained in the docs, It accepts an Array of functions to execute, as a pipeline, whenever the model value changes. The functions are called in reverse array order, each passing the value through to the next. The last return value is used as the actual DOM value. Used to format / convert values for display in the control.


So basically $parsers and $formatters are the workers who modify the values passed between the model and the view , In the example below, you can see that we have added a function in the formatter pipeline which will transform the model value to uppercase . 


function formatter(value) {
  if (value) {
    return value.toUpperCase();
  }
}
ngModel.$formatters.push(formatter);

$setViewValue : According to the docs, It Updates the view value.
This method should be called when an input directive want to change the view value; typically, this is done from within a DOM event handler.
For example input calls it when the value of the input changes and select calls it when an option is selected.
Again , you should understand that it updates the $viewValue and does not update the value in the view which is visible to you . $setViewValue will automatically call the $parsers and $validators pipeline. 
$validators is a simple concept , it is just a  collection of validators which are applied whenever the model value changes. AngularJS Docs are enough to understand it. 
You can see all these in action in the following plunker link 
So, here the 'Change Model' button will activate the Model->View pipeline , and you can see the $formatter in action , it converts the model value to uppercase and the value is rendered to the View using the $render function . 
And if you type in any value in the div element and click anywhere in the screen , it will activate the View->Model pipeline , $setViewValue and $parser is run , and the value is updated in the model in the uppercase form . 
$setViewValue is called inside $apply because we are calling it inside elm.on() , which is jquery . Since it is outside the AngularJS realm, to use any AngularJS feature inside it, we have to run it inside $apply . 

There are hell lot of properties and methods of ngModelController, but my aim with this doc was only to explain the bare minimum which you need to use two way data binding . You can understand the application of other properties and methods once you understand how the controller achieves what it is supposed to achieve. I hope this post eased your pain a bit . 

* Grabs a beer * 


Forms in angularJS (ngFormController)

Forms in angularJS are quite advanced then the normal HTML forms, and they work wonders with ngModelController. ngModelController, along with keeping the model and view in sync( by $formatters and $parsers) also helps in validating the data and checking if the value was changed from its default ( this is achieved by $pristine,$dirty,$valid,$invalid properties and by using the respective css classes) . There are a lot many properties and methods of ngModelController but we will mention these four for simplicity .

ngModelController.$pristine returns true if the value of the input field has not been changed from its initial state .

ngModelController.$dirty returns true if the value of the input field has been changed from its initial state .

ngModelController.$valid returns true if the value of the input field is valid (as the name suggests)

ngModelController.$invalid returns true if the value of the input field is invalid.

Now, a form directive (or ngForm) creates an instance of ngFormController . Each ngFormController does the same thing as ngModelController but for the whole form, instead of only an input element(in case of ngModelController) .

Now, how does it do it? Using the underlying ngModelControllers. Each ngModelController registers itself to its parent form, if there is any. The ngFormController also has the same properties and methods as ngModelController ( except $addControl(), $removeControl() , $setSubmitted() methods ) , so it sets its properties like $invalid,$valid,$pristine,$dirty according to the underlying ngModelControllers (like if any input ng-model field is set to $invalid, then the ngFormController is set to $invalid ) .

You should keep in mind , that any form elemnt creates an instance of ngModelController , like if you write like :
<form name="userForm">
</form>


ngFormController will be instantiated and css classes will be added to them instantly:

In developer tools , you will see

<form name="userForm" class="ng-pristine ng-valid">
</form


Now these properties of ngModelController and ngFormController can be used to do validation and other stuffs . Like , suppose you want to do the validation in a url input field , like show an error text if the url field is empty, and show an error text when the url is not a valid one. These can be very easy as ngModelControllers have built in validation for input types and you merely have to do this::

<form name="userForm" ng-controller="FormController">
<input type="url" name="url" ng-mode="url" required>
<span ng-show="Error(userForm.url, 'required')">url field should not be empty</span>
<span ng-show="Error(userForm.url,'url')">url is not valid</span>
</form>


and in the FormController:
.controller('FormController',function($scope){
$scope.url=' ';
$scope.Error=function(ngModelController,error){
return ngModelController.$error[error];
}
});


So this Error function takes in the ngModelController and the error type. So, how did we reference the ngModelController .
By the 'name' attribute we can reference the ngModelController. Syntax is : <name_of_the_form>.<name_of_the_directive_which_has_ng-model> .
And ngModelController has $error property , An object hash with all failing validator ids as keys.
In this case, the validator ids are 'required' and 'url' .

And you can check the validity of the whole form with "userForm.$error[]". Then we can disable the submit button, or disable a save button or any action which the user performs only when the form is valid, simply by calling a function which checks $valid property of the form .

<form name="userForm">
   <button ng-disabled="cannotSave()"></button>
</form>
.controller('FormController',function($scope){
  $scope.cannotSave=function(){
return $scope.userForm.$invalid ;
}
});


We have seen and understood the behaviour of form attribute in AngularJS , but what about ng-form, and why is it even there when we can achieve everything through form attribute . We missed out one thing, which cannot be achieved by form attributes :--' Nesting of forms' .
Using a form attribute inside another form attribute is invalid HTML , so AngularJS came up with ng-form . We can  nest any number of ng-forms inside form attributes and inside each other .

One very useful usecase is the the use of subforms as reusable components , which will reduce repeated code . Suppose we want to use the above url input form as a reusable component and embed it inside another form . Lets create a simple form which only has a FirstName and LastName input field .

<form name="parentForm">
<input type="text" name="firstname">
<input type="text" name="lastname">
<ng-include src="'urlform'"></ng-include>
</form>


we have included the form with ng-include . Now, the structure of the reusable form will be :

<script type="text/ng-template" id="urlform">
<ng-form name="userForm" ng-controller="FormController">
<input type="url" name="url" ng-model="url" required>
<span ng-show="Error(userForm.url, 'required')">url field should not be empty</span>
<span ng-show="Error(userForm.url,'url')">url is not valid</span>
</ng-form>
</script>


Notice that we have copied the whole code of the url form we had , and just replaced form with ng-form and it did the trick .

Also, we might have fields in a form which needs to be repeated and added dynamically, like the addresses of social networking sites you are active in, because someone has less number of  profiles and someone has more . We need to add fields with an 'Add' button , which will create an input field, and also we need to have validation in each of these fields.
Now, suppose we dont use ng-forms , then we will fully rely on ng-repeat directive , which will repeat the input fields . But each of this input fields dont have any identifier, like a name attribute or something , and we cannot generate  dynamically name attributes through angularJS for input directives .
What we can do in such situation is give an ng-form attribute in the directive which has ng-repeat
<div ng-repeat ="website in user.websites" ng-form="userForm">

Now, this will create a userForm for each each website in user.websites, and we can reference the ngModelController of the ng-model attributes inside this ng-form .

You can see this example from this link here .

So, this is what i had to discuss about Forms in AngularJS. Hope, you could make something out of it, and do give feedbacks .



Scopes in directives of AngularJS

For this blog , you need a basic understanding about custom directives in AngularJS .

Scope is a concept of AngularJS which can be pretty tricky at times, and can get difficult to make sense out of it . Thanks, to some extensions, like batarang , we can check the scope IDs of elements and check which have same or different scope.   All DOM elements that have been compiled by AngularJS have a scope associated  with them. In most cases DOM elements do not have scopes defined directly on them but get their scope from some ancestor element. New scopes are created by directives that specify a scope property on their directive definition object( will talk about that in a short while) .  If we talk about built in directives of AngularJS, then only a few core directives define new  scopes, these are ng-controller, ng-repeat, ng-include, ng-view, and ng-switch. They all create child scopes that prototypically inherit  from their parent scopes.
And when we create a custom directive using app.directive  , which uses a  service called $compile and its provider  $compileProvider , we also create a scope(or not) based on our requirements. If you are wondering what this $compile is, $compile is at the heart of AngularJS machinery and can turn HTML strings (with directives and interpolation expressions) into live DOM.  We can add our own functionality to this compilation process using the compile property like ::

app.directive('myDirective',function(){
return{
compile: function(element,attrs){
// here we can add functionality to be run during the compile phase
}
}
})

I will tell in detail about the compile (and about creating a custom directive as a whole) in a later blog.

Now, getting on with the scope thing, the directive service has a scope property, which defines the scope of the directive which we are creating ..
There are, three options for the scope directive ::

app.directive('myDirective',function(){
return{
scope: true //or scope: false //or scope:{}
}
});

scope:false is the default value. Now, what does  these actually mean . 
Put in simple words, scope:false , means that you dont want a separate scope for this directive. It is also called 'shared scope' . Shared scope simply means that the directive works with the same scope that is already available for the DOM node where the directive appears without creating a new one. 

scope: true,  means 'inherited scope' , 
In this case, a  new scope is created for our directive, but it inherits all the properties of the parent scope through JavaScript's prototypical inheritance: when the directive accesses a property on it's new scope, the property is first searched on the current scope and if it's found then it's value is returned, otherwise, if it's not found, the same property name is searched in the parent scope and that value is returned (the search traverses all the parents until the property is found or until there are no more parents); if a value is assigned to a property on the new directive's scope and the same property already exists in the parent, accessing the property value directly in the new scope will in fact override the parent's property value and any change to the property in the parent will not be propagated anymore to the child scope.

and, the one used most commonly is  scope:{ }, which means isolated scope .
As its name suggests, it is an isolated scope, which has no connection with the parent element in which it resides, though it can access the parent element by $parent, but its functionality is not affected by the scope of the parent in which it resides.

We can however have connection between the isolated scope, and the parent scope in terms of accessing data or methods or enabling data binding. There are three types of interface we can specify
between the element's attributes and the isolated scope: interpolate (@) , data bind (=) , and expression (&) .

The various options available with the scope are ::
scope:{
key1:'@attribute1',
key2:'=attribute2',
key3:'&attribute3'
}

These are written in form of key: value pairs .The key is the name of the field on the isolated scope. The value is one of @ , = , or & followed by the name of the attribute on the element. If you omit the attribute names::

scope:{
key1:'@',
key2:'=',
key3:'&'
}
then key1, key2, key3 will be taken as the attribute names.. Now, i am having the temptation to blurt out the whole directives concept here, but i will refrain myself :P and talk about the directives(along with the scope options above) in a separate blog, to make this blog to the point :) .

Ok, so  let me give examples of all these scope variations in terms of scope ids::

Shared Scope:::

Parent Scope Id: 002
Directive Scope Id: 002
(they are bound to the same scope)

Inherited Scope::

Parent Scope Id : 002
Directive Scope Id : 003( but is inherited from the parent scope)

Isolated Scope::

Parent Scope Id: 002
Directive Scope Id : 004(is completely isolated from the parent scope)


Now, what if multiple directives with different scope variations appear on a single HTML DOM node.
The way they interact with each other changes a little bit in these cases..


   1) If there are only  shared scope directives, then they will behave as usual, and share the parent scope.

  2) If there are only inherited scope directives, then they will all be bound to a single scope inherited from the parent scope.

  3) If there are mix of shared and inherited scopes, then the shared scope will also behave as inherited scope , and all these directives will be bound to a single inherited scope .

  4) There can only be a single isolated scope directive on a DOM node .

  5) If you mix one isolated scope directive to any bunch of directives mentioned in 1)  2) 3) , then others will behave as mentioned in these points, along with one isolated scope created for this  isolated scope directive.

So, this is all i had to talk about scopes . Thanks, for giving it a read and do add additional info on these :)

Various formats of referencing directives in angularJS

We can use a variety of naming conventions to refernce directives in HTML markup . In Angular JS all the directives are accessed in modules as camel case like 'ngResource' or 'ngModel' .
But in an HTML template, there are various methods to access the directive . Like for ngModel ,  we need to use either snakecase form (ng-model), colon-separated (ng:model) or the underscore-separated (ng_model) form. Additionally, each reference to a directive can be prefixed with either x
or data.

So, to say , the combinations we can use are ::
ng-model, ng:model, ng_model, x-ng-model,
x-ng:model, x-ng_model, data-ng-model, data-ng:model,
data-ng_model, x:ng-model, data_ng-model, and so on.


The functionality of all of these are equivalent , however they hold some meaning behind there naming conventions .

The data prefix for example is used to for keeping our HTML documents HTML5-compliant, and making them pass HTML5 validators tests.
The HTML5 spec allows for arbitrary attributes as long as they're prefixed with data- , ex:
<div data-customattribute=""> </div>


works fine , but
<div myattribute=""> </div>
  
will become invalid html .

A custom data attribute according to html 5 specs is basically  an attribute in no namespace whose name starts with the string "data-", has at least one character after the hyphen, is XML-compatible, and contains no characters in the range U+0041 to U+005A (LATIN CAPITAL LETTER A to LATIN CAPITAL LETTER Z).

If you are wondering how to make something XML-compatible, follow this link : XML-Compatible

These custom attributes are private to the page and can be used only in that scope, and connot be accessed by external software.

Now, to see an example of custom attribute, suppose you want to sort songs by the length of its track (this example is given in w3 site) , then you can create a custom attribute like :
<li data-tracklength="3m2s">Some Song</li>

this attribute can be used to sort the songs according to there length, or filter tracks according to track length in the site itself .


Now, to talk about the x- or x: attribute, as you can guess, it is used to make documents XHTML compliant , like :
<div x:attribute=""></div>


However, XHTML is not so popular these days .


I could not find any difference in semantics between snakecase model, colon-sparated model . Maybe it was just created for ease of people of different coding styles.

Hope, this clears something . Do update any relevant information in the comments .

Thanks :)


Promise API($q) explained in angularJS

Promise API may sound like an unncessary complexity but it helps a great deal in making the chaining of function calls and handling exceptions bearable . While, these things seem pretty easy in the synchronous world, it becomes very perplexing in the asynchronous javascript world.

AngularJS comes with the $q (Pomise API) , which is lightweight . Many Angular services like $http, $timeout and others heavily rely on promise style APIs (they return a promise, by default) , so it is a good idea to get familiar with $q in order to use those services effectively , and in order to manage your numerous asynchronous events .

 In case you are confused what a promise actually means , you can understand it from an example : Suppose , you ask your friend to bring a Pink Floyd T-shirt from a store . Now, if your friend promises you that he will bring you one , then its a promise (quite obvious :P ) . There are two scenarios now, either he can fulfill the promise or he cannot . Make sure you understand that the task you gave to your friend is asynchronous, you can do other tasks while he tries to fulfill the promise . Again, if he is successful in fulfilling the promise, there can be other outcomes like 'If you liked the T-shirt' ,'If T-shirt was not of your size' etc (we can chain these events).

Lets take this example , and try to understand the $q API and its various functionalities .

lets create a person constructor and pass name and $log service as arguments to it .
( name refers to the name of the person who asked for the T-shirt). we will add methods to be called during the success or failure of the promise here.
var Person=function(name,$log){
this.gottshirt=function(value){
$log.info(name+ "got his t-shirt" + value);
};
this.didntget=function(reason){
$log.warn(name+ "didnt get the t-shirt because" + reason );
};
} ;


Now, we will create various scenarios as Jasmine Tests to illustrate the usage of $q .Jasmine is a  behaviour -driven development framework for testing Javascript code.

Lets, see the basic usage first :

First, inject the various dependencies , to be assigned before every test begins. beforeEach is a function which is used to inject dependencies and create variables and objects , which are mandatory for every running instance of the test.
beforeEach(inject(function(_$q_,_$log_,_$rootScope_){
$q=_$q_;
$log=_$log_;
$rootScope=_$rootScope_;
aakash= new Person('Aakash',$log);
}));


 In the beforeEach function, I am creating a new user Aakash , who ordered his friend for a T-shirt ,
 now , his friend is basically a service which is used by Aakash .

Now lets start a test suite. A test suite begins with a call to the global Jasmine function 'describe' with two parameters: a string and a function . The string is a name or title for a spec suite(like what test we are running). The function is a block of code that implements the suite.
describe ('$q used in a service ' , function(){
var friend=function($q,$rootScope){
var deferred;
this.goingtobuy=function(){
deferred=$q.defer();
return deferred.promise;
}
/* here , the call to the $q.defer() method  returns a deferred
object. Conceptually it represents a task that will be completed (or will fail in the
future). The deferred object is used for two things
     1) It holds a promise object (in the promise //property). Promises are placeholders for the future //results (success or failure) of a deferred task.
 2)It exposes methods to trigger future task completion ( resolve ) or failure (reject)*/
this.has_bought=function(){
deferred.resolve();
$rootScope.$digest;
}
 //the resolve method triggers the completion of task .
this.notfound=function(reason){
deferred.reject(reason);
$rootScope.$digest;
}
//the reject method triggers the failure of task.
});
// here i am creating an instance of a friend called  thomas, before each test suite starts.
      var Thomas;
      beforeEach(function () {
        Thomas = new friend($q, $rootScope);
      });


 'it' is a jasmine function which runs each spec or test . Here, we are running a test for the case when the promise is not fulfilled.


    it('should illustrate promise failure', function () {
/*here i am creating a deferred object 'shirtOrdered' . the 'then' method registers callbacks if the task is successful or promise is fulfilled (as the first argument) , and if task is failed(as the second argument).*/
        var shirtOrdered = Thomas.goingtobuy();
        shirtOrdered.then(aakash.gottshirt, aakash.didntget);
/* we have triggered task failure (notfound method). Expect function calling is quite verbose , like in this case, it tells to expect $log.warn.logs to contain the given string.*/
        Thomas.notfound('No Pink Floyd Tshirts, sold out ');
        expect($log.warn.logs).toContain(['Aakash didnt get the t-shirt because No Pink Floyd Tshirts, sold out']);
      });
// this test is for the case of promise fulfilment.
      it('should illustrate promise success', function () {
        var shirtOrdered = Thomas.goingtobuy();
        shirtOrdered.then(aakash.gottshirt, aakash.didntget);
        Thomas.has_bought();
        expect($log.info.logs).toContain(['Aakash got his T-shirt']);
      });
});


Hope, this post gives you some insight of the promise api in angularJS .  Do tell me if i am wrong anywhere .