Angular 2


·         Release: AngularJS - 2010, Angular2 - 2016, Angular4 - 2017
·         Why Angular2 over AngularJS?
o   AngularJS is based on Controller whereas Angular2 is based on Component, so angular2 provides features like modularity, reusability, testability
o   Angular2 is five times faster than AngularJS
o   Angular2 provides Mobile App development support
o   Angular2 provides more language choices like: JS, TS, Dart, PureScript, ELM etc.
·         Angular4 over Angular2
o   Angular4 is backward compatible with Angular2
o   Angular4 has reduced compiler generated code
o   Animation feature is pulled out from angular/core and moved to their own packages
o   We can use if-else syntax using *ngIf in Angular4
·         Environment setup for first sample app:
o   Install Visual Studio 2015, Node.js and TypeScript for Visual Studio 2015
o   In Visual Studio, Click on Tools – Projects & Solutions – External Web Tools: move $(path) above, Web Tools/..External – ok
o   Create ASP.Net Empty Web Application
o   Download QuickStart from http://github/angular/quickstart
o   Copy, src, bs-config.json, package.json, tslint.json and paste to root directory of new project
o   Include recently pasted files. Right click on package.json and click Restore Packages
o   Open command prompt, navigate to root of project and hit npm start command
·         Modification to run above Angular project in Visual Studio using F5:
o   Index.html
§  base href = ‘/src/
§  /shim.min.js
§  /zone.js
§  /system.src.js
o   Systemjs.config.js
§  ‘npm’:’/node_modules/
o   Tsconfig.json
§  “CompileOnSave”: true
·         Component is a class with Template and Decorator in angular
·         Template defines the User Interface, HTML and Data Bindings etc
·         Class contains the code that is required for the template
·         Decorator adds metadata to a class to make it is angular Component
·         Sample Component
o   import {Component} from “@angular/core”
o   @Component({ selector:’selectorToAddComponent’, Template: ‘HTML Template’})
o   export class ComponentName{ property = ‘value’;  method(); }
·         Ways to style a Component
o   External: Add styles in Style.css in root directory
o   Inline: In Component HTML file in style attribute
o   Internal: in Component HTML file within <style> tag
o   Components Styles property
o   Components StyleUrls property
·         Interpolation and Property Binding both are used for one way data binding from Component class to template. Interpolation is simple and convenient approach provided by angular, internally it does property binding
o   Interpolation: src = {{VariableThatHoldsValue}}
o   Property Binding: [src] = VariableThatHoldsValue or  bind-src = VariableThatHoldsValue
·         If we have to set string value (concatenation) to the property, we must use Interpolation. E.g.: innerHTML = {{‘Welcome’ + UserName}}
·         If we have to set non string value (Boolean) to the property, we must use Property Binding. E.g.: [disabled] = ‘isDisabled’
·         Interpolation and Property Binding are used to bind Class Properties to HTML Properties not HTML attributes. To bind HTML Attributes, we use attr.AttributeNam. E.g.: attr.ColSpan = {{SpanValue}}
·         Properties Value can be changed but Attribute Value cannot be changed. Attributes value used to initialize the HTML elements
·         Class Binding is used to set CSS Class to HTML element. E.g.: [Class] = VaribaleForClassName’. This will remove all existing styles and add assigned classes to the HTML element. To keep existing classes as is and to add/remove class, we can modify class binding as [class.ClassName] = SetOrNotSetVariable’. For multiple class we use, [ngClass] = ListOfClasses’; ListOfClasses = {Class1: true, Class2: false ;…}
·         Style Binding is used to set CSS style to an HTML element. E.g.: [style.styleName] = styleValue. Style property name can be written in dash case or camel case. E.g.: font-size/ fontSize. Style that requires unit value, can be set as: [style.fontSize.px] = size’. [ngStyle] used for applying multiple styles to an HTML element similarly as we use [ngClass]
·         Event Binding is used for event handling and passing data from HTML element to component class. E.g.: <button (click) = onClickFunction()> or <button (on-click) = onClickFunction()>. To get data from HTML element to component class we use (input) = classVariable = $event.target.value’ or we can use [(ngModel)] = classVariable for the same purpose. ngModel is combination of both event binding and property binding so it is used for two way binding. To use ngModel, we must import FormModule from angular/forms package in app module.
·         *ngIf is a structural directive used to hide/show an HTML element depending on its Boolean value. E.g.: <div *ngIf = HideOrShow>
·         *ngFor is a structural directive used for repetitive HTML elements. E.g.: <tr *ngFor=’let employee of Employees;’> where Employees is a collection. *ngFor provides following features:
o   let i = index; //Returns the index of current record
o   let isFirst = first; //Returns TRUE if it is first record
o   let isLast = last; //Returns TRUE  if it is last record
o   let isEven = even; //Returns TRUE  if it is even number record
o   let isOdd = odd; //Returns TRUE  if it is odd number record
·         trackBy: *ngFor is not suitable for large amount of records [performance issue] because it recreates all HTML elements if the collection object is gets updates. To overcome this issue, we use trackBy. E.g.: <tr *ngFor=’let employee of employees; trackBy:TrckByEmployeeCode >..</tr> where TrackByEmployeeCode(index, employee) is a function which will return current employeeCode.
·         ng-container: We cannot use multiple structural directive (e.g. *ngIf and *ngFor) in single HTML element so to handle scenario where we need multiple structural directive we can use ng-container.
·         E.g.: <ng-container *ngFor=’CodeToIterateThroughCollection’>
            <tr *ngIf=’ConditionToShowRecordOrNot’> </tr> </ng-container>
·         Pipes are used for transform data before display. E.g.: {{variable | pipeName}}. We can use multiple pipes for single HTML element. Angular provides following important pipes:
o   uppercase / lowercase
o   date : ‘format’ E.g.: dd/MM/yyyy, fulldate, shortdate, medium, longdate
o   currency : CurrencyName : ShowCurrencySymbol : MinDigits.MinDigits-MaxDigits
·         We can have our custom pipe by implementing transform() method of PipeTransform interface
o   import { Pipe, PipeTransform } from ‘@angular/core’
o   @Pipe({ name: ‘NameOfThePipeToBeUsedInComponentHTML’ })
o   export class ClasNameThatImplementCustomPipe implements PipeTransform {
transform(value:string, additionalParameters : any){
 //custom code
}}
o   Include pipe in declaration of application module
o   Use pipe in any component as: {{property | pipename : parameterIfAny}}
·         Nested /Child Component is a component that is included into another component. To nest a component, include the selector of child component into the HTML template of parent as directive.
·         Input Property is used to get data from parent component. Steps to use Input Property:
o   In child Component: import {Input} from ‘@angular/core’;
o   Decorate class property with @Input() to make it as Input Property. E.g.:
@Input()
ParentValue: string;
o   In parent template: <childSelector [PropertyName] = ‘ValueToPass’>  E.g.:
 <EmployeeDetails [Total] = ‘getTotalEmployeeCount()’>
·         Output Property is used to send data to parent component. We can pass event handler to parent component to handle event at parent component as below:
o   In child component: import {Output, EventEmitter } from ‘@angular/core’;
o   Create event handler using EventEmitter class and mark it as Output property as:
@Output()
myEventHandler : EventEmitter<EventPayload/ parametersToPass> = new EventEmitter<EventPayload/ parametersToPassToParentComponent>();
o   Emit handler from child event as:
functionCalledFomChildComponent(){
        this.myEventHandler.emit(parametersToPassToParentComponent);
}
o   In parent template assign parent function to child output property/event handler as:
<ChildComponent (ChildEventHandler) = ‘ParentFunction($event)’></ChildComponent>
·         Interface: TypeScript is strongly typed language so generally we use string, number, boolean etc predefined data types but if we want a user defined custom data type then we can use Interface. We can declare interface as: export interface InterfaceName{} and use as : className implements InterfaceName
·         Short-Hand-Syntax used to initialize properties in constructor as: constructor(AccessModifier propertyName: DataType){}. E.g constructor(private _employeeName: string){}
·         Angular Component Lifecycle Hooks: methods which can be used as lifecycle event.
o   ngDoCheck
o   ngComponentInit, ngComponentChecked
o   ngViewInit, ngViewChecked
o   ngOnChanges called every time the value of a class property change.  This provides us old & new value of the property
o   ngOnInit called only first time after ngOnChanges and constructor. Generally used for component initialization, data retrieval etc.
o   ngOnDestroy called on component destruction. Generally used for cleanup code.
·         How to use lifecycle hooks:
o   Import {OnChanges} from ‘@angular/core’;
o   Import {SimpleChanges} from ‘@angular/core’; // required for OnChanges
o   export class ClassName implements OnChange{}  //writing implements is optional here
o   implement OnChanges as:
ngOnChanges(changes: SimpleChanges){
        for(let propertyName in changes){
                let change = changes[propertyName];
                let current = JSON.Stringyfy(change.CurrentValue);
                let previous = JSON.Stringify(change.PreviousValue);
}
}
·         Angular Services are used when we want to reuse data across multiple components. We can write service as below:
o   import {Injectable} from ‘@angular/core’
o   decorate class by @Injectable() to inject dependency in service
o   export class ServiceName {}
o   Add functions that you want to expose from service e.g.: getEmployees(){}
·         We can access angular services as below:
o   import {ServiceName} from ‘./AngularServicePath
o   create object of service as: constructor( private _service: ServiceName){}
o   Register service using [provider] directive either in @Component({}) or in @module({})
·         Usually services are called from ngOnInit() hook not from constructor to not to make page busy.
·         How to call API from angular:
o   In root module, import { HttpModule } from ‘@angular/http’;
o   Include HttpModule in imports[] of root module
o   In service class, import { Http } from ‘@angular/http’;
o   Create instance of Http: constructor(private _http: Http){}
o   Now we can use _http (instance of Http) to call API using GET, PUT, POST etc functions.
o   These functions returns Observable<Response> which we need to handle as per our requirement using map (to handle response) and subscribe (to handle callbacks).
·         Example to call API:
o   Import { Injectable} from ‘@angular/core’;
o   Import { Http, Response } from ’@angular/http’;
o   Import { Observable } from ‘rxjs/observable’;
o   Import ‘rxjs/add/operator/map’;
o   @Injectable()
o   Export class TestService {
o   Constructor (private _http: Http){}
o   TestServiceMethod () : Observable<any>{
o   return this._http.get(‘ServiceURL’).map((response: Response) => <any>resonse.json()); }
·         Observable is an async pattern in which:
o   Observable, emits data and notify / executes callback function.
o   Observer/ Subscriber, subscribes to observable with callback function.
o   One observable can have multiple subscriber
o   We can subscribe service from any component as:
o   this.ServiceName.ServiceMethodName(ParamsIfAny).subscribe((data)=>{ // some code });
·         Subscribe method has following three parameters:
o   OnNext: This function executes once data emitted by observable
o   onError: This function executes if any error occurred
o   onComplete: This function will be called after all data is emitted i.e. it executes after onNext for the final item
·         Error Handing in service is done by using catch/throw operator of rxjs as below:
o   Import ‘rxjs/add/operator/catch’; //we can use throw as well
o   In service call, this._http.get(‘URL’).map().catch(errorHandlerFunction);
o   E.g. errorHandlerFunction(error: Response){
o   return Observable.throw(error); }  //This will throw error to subscriber
o   In subscriber, this.ServiceName.ServiceMethodName().subscribe(SuccessCallback, (error) => ErrorCallback(error)); // Here we can handle error as per requirement
·         Retry in observable is used to recalling the service in case of error as below:
o   Import ‘rxjs/add/operator/retry’;
o   In subscriber component, this.ServiceName.ServiceMethod().retry(RetryCount)subscribe(); //If RetryCount is not mentioned it will try infinitely
·         RetryWhen in observable is used when we want to recall a service after some delay or on some condition. We can use it as below:
o   Import ‘rxjs/add/operator/retrywhen’;
o   Import ‘rxjs/add/operator/delay’;
o   Import ‘rxjs/add/operator/scan’;
o   In subscriber component, this.ServiceName.ServiceMethod().retrywhen((error)=>error.delay(1000))subscribe(); //This will retry calling service (in case of error) after I second (1000 milliseconds)
o   We can use scan() of error to get the details of retry in retrywhen as:
retryWhen((error) => {
return error.scan((retryCount) => {
retryCount += 1;
 if(retryCount < 6)
return retryCount;
else
 throw error;  }); });
·         Unsubscribe in observable is used cancel the retry/ recall service as below:
o   Import { ISubscription } from ‘rxjs/subscription’;
o   Create instance of IScubsciption, private _subscription: ISubscription;
o   Set subscriber instance, _subscription = this.ServiceName.ServiceMethod().subscribe(…);
o   In function where we want to unsubscribe, this._subscription.unsubscribe();
o   _subscribe.closed property used to get the status of subscription.
·         We can use Promise instead of Observable as:
o   Import ‘rxjs/add/operator/toPromise’;
o   serviceMethod() Promise<any>{
o   return this._http.get(‘URL’).map().toPromise().catch(promiseErrorHandler);}
o   Error Handling in observable:
§  Observable.throw(error);
o   Error Handling in Promise:
§  throw (error)
o   In service calling component, this.ServiceName.ServiceMethod().then().catch();
·         Promse vs Observable:
o   Promise emits single value, observable emits multiple values over period of time
o   To call service:
§  .then(successCallback, errorCallback);
§  Subscribe(onNextCallback, onErrorCallback, onCompleteCallback);
o   Promise is not lazy, observable is lazy. Observable is not called until we subscribe the observable. If we don’t have subscribe() then service is not called but even if we don’t have then() still service gets called.
o   Promise cannot be cancelled. Observable can be cancelled using unsubscribe()
o   Observable provides different operators like: map, forEach, filter, retry, retryWhen, reduce, unsubscribe.
·         Routing is used to navigate from one view/component to another as below:
o   In root module, import {RouterModule, Routes} from ‘@angular/router’;
o   Declare RouteModule in imports[] of root module
o   Declare routing path as:
§  const  appRoutes: Routes = [
§  {path: ’pathOne’, component:  componentName}, //Normal Route
§  {path: ‘pathTwo/:param’, component: ComponentName}, //with param as parameter
§  {path: ‘’, redirectTo:’/SomePath’, pathMatch: ‘full’}, //Empty Route
§  {path: ’**’, component: pageNotFoundComponent}]; //Invalid Route
o   Set routes as: imports[RouteModule.ForRoot(appRoutes, {useHash=true})]
o   Use routerLink attribute to navigate from component HTML. <li routerLink=’Home>
o   Use <router-outlet></router-outlet> as placeholder for routed component
o   If we don’t use hash style routing and use default HTML5 routing then we need to add re-write rule in web.config as:
§  <system.webServer><rewrite><rules>
§  <rule name=’RuleName’ stopProcessing=’true’>
§  <match url=’.*’ />
§  <conditions logicalGrouping = “MatchAll”>
§  <add input=”{REQUEST_FILENAME}” matchType=”IsFile” negate=”true” />
§  <add input=”{REQUEST_FILENAME}” matchType=”IsDirectory” negate=”true” />
§  </conditions><action type=”Rewrite” url=”/src/” /> </rule></rules></rewrite>…
o   routeLinkActive=’activeClassName attribute is used to set a class if RouteLink is active
o   To set routingLink with parameter: <a routerLink=”[‘/Home’, pram]”> where first parameter is path of route and second parameter is parameter to route
o   Read route parameter from URL:
§  import { ActivatedRoute } from ‘@angular/router’;
§  constructor(private _activeRoute: ActivatedRoute){}
§  this._activeRoute.Snapshot.params[“parameterName”]
o   navigate() method used to navigate to a route as :
§  import { Router } from ‘@angular/router’;
§  constructor (private _router: Router) {}
§  this._router.navigate([‘/Home’]);
·         Dependency Injection is a coding pattern in which a class receives a dependency from an external source rather than creating itself. For example, to use angular service we use constructor(private _serviceObject: ServiceName){} this short hand syntax, but we don’t see new() which actually creates the object. Here Angular Injector creates/ provides the singleton object of the service to us and to know the injector about dependency we register service in component/ module using [provider].
·         Why dependency injection? Before DI, we need to create object of service explicitly, which has following drawbacks:
o   Difficult to maintain: if service constructor definition change then we needs to update it everywhere it is used. In case of DI we are not explicitly creating object.
o   Sharing: Instance created by class is local to that class so we cannot share data and logic across components
o   Difficult to Unit Test
·         Getter and Setter in TypeScript:
o   get propertyName(): returnType { return privateVariableValue; }
o   set propertyName(value: DataType) { privateVariable = value; }