Angular 2 – Passing data to child components

It is very common requirement to pass the data from Parent component to child component. In angular this can be achieved using using the @Input decorator, to define an input for a component, we use the @Input decorator. This decorator tells Angular to treat passed value as an input binding

Below is the Partner Component which has child component Partner contacts, their HTML looks some thing like this
Partner Component

{{partner.name}} {{partner.website}}
<app-partners-contacts-list [contacts]="partner.contacts"></app-partners-contacts-list>

Inside partner component we have child component partner contact list

<app-partners-contacts-list [contacts]="partner.contacts"></app-partners-contacts-list>

Partner Contact List: As u can see for the child component we are setting the partner.contacts array value to the the contacts @Input property on the child component. Child component looks some thing like this

import { Component, OnInit, Input } from '@angular/core';
import { PartnerContacts } from './../../partner.model';
@Component({
  selector: 'app-partners-contacts-list',
  templateUrl: './partners-contacts-list.component.html'
})
export class PartnersContactsListComponent implements OnInit {
  @Input() contacts: PartnerContacts[];
  constructor() { }

  ngOnInit() {
    console.log(this.contacts);
  }

}

As you can see we have declared an @Input property inside the child component so that we can set the this value from parent component.

HTML : It just a table iterating through contacts array.

Angular 2 Custom Pipes

In Angular 1.x we had used Filters extensively be it inbuilt ones or the custom ones. In Angular 2.x filters have been re-branded/renamed to Pipes. Below is an example for building custom pipes in Angular 2.x.

Below is the grid for displaying list of persons and as you type in the something in search criteria it will apply that filter criteria to person name property and filter the grid items.

personlist

personfilteredlist

For creating custom pipes you need to create class that implements PipeTransform Interface, this class is then decorated with @Pipe decorator. From the PipeTranform interface you need to implement transform method, below is the code snippet for the same.

import {Pipe, PipeTransform } from '@angular/core';
@Pipe({
    name: 'personSearch'
})
export class PersonSearchPipe implements PipeTransform {
    transform(items: Array, searchValue: string){
        if (searchValue){
            return items.filter(item =>{
                if (item.name.indexOf(searchValue) > -1){
                    return true;
                }
                return false;
           })
        }
        else{
            return items;
        }
    }
}

You need to register the PersonSearchPipe to component module like show below

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';
import { PersonSearchPipe } from './personSearch.pipe';
@NgModule({
  declarations: [
    AppComponent,
    PersonSearchPipe
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule
  ],
  providers: [],
  bootstrap: [AppComponent],

})
export class AppModule { }

 

In the HTML for the component add the filter like shown below

personlisthtml

Attached is the source code over here, to run the source please set up angular-cli and do npm install

ES6 + Arrow Function + Mystery with this

We have been using arrow function for quite some time in compile languages like C#, but the same is now available in java script.

An arrow function is short hand, we can leave off the function keyword and we can leave of the return statement. Even though it kind of short hand operator, but its main purposes is to get away from nuances of this keyword in javascript. First we will cover basics around arrow function then discuss nuances around this keyword.
Consider the following example

(function () {
    'use strict'
    var getName = () => "aamol";
    console.log(typeof getName);
})();

What will be the output? It is going to be function, so essentially we are declaring a function but in a short hand way. Now if we execute that function what will be the output, it would be “aamol” 

(function () {
    'use strict'
    var getName = () => "aamol";
    console.log(getName());
})();

So again as mentioned above we can leave off the return keyword in an arrow function, whatever expression is specified over there will get returned. Here is another example of arrow function

(function () {
    'use strict'
    var getName = lastName => "aamol" + " " + lastName;
    console.log(getName("gote"));
})();

So in case if we have one argument to the function then we can leave off the parenthesis. It will output “aamol gote”. Now in case if you have more than 2 parameters then we have 2 use parenthesis. Output would be the same “aamol gote”. 

(function () {
    'use strict'
    var getName = (firstName, lastName) => firstName + " " + lastName;
    console.log(getName("aamol", "gote"));
})();

Now there would be scenarios where you will have more than single expression, then how does the arrow function look like shown below, your arrow function should return some thing.

(function () {
    'use strict'
    var getName = (firstName, lastName) => {
        if (firstName && lastName) {
            return firstName + " " + lastName;
        }
        else if (firstName && !lastName) {
            return firstName;
        }
        else if (!firstName && lastName) {
            return lastName;
        }
        else {
            return null;
        }
    }
    console.log(getName("aamol", "gote"));
})();

As discussed above real purpose of arrow functions is to handle this key word within functions, “this” has always been confusing aspect of JavaScript and in ES6 arrow functions make it easier to understand. Consider following example what would be the output?

    document.addEventListener("click", function () {
        console.log(this)
    });

Output will be “#document” in chrome browser.

Whenever we have an event handler in java script, this gets set to the element that receives the event and this caused problems in ES5 because we could not get access to the context of the function. Now consider the same example with arrow function

'use strict'
document.addEventListener("click", () => console.log(this));

Output will be “#Window” in chrome browser.

We are in the global area over here and not in the context of a function so this refers to the context of code in which we running which is window a global object. So as long as we are using arrow functions this will not be set to the element that is getting the event it is going to be set to the context in the code which are running in.

Lets consider another example,

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function () {
        console.log(this);
    }
}
person.getName();

What would be the output, it would be person object
{age: 34, firstName: “aamol”, lastName: “gote”}

Now we will replace getName function with arrow function

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName:  () => console.log(this)
}
person.getName();

Output over here would be window object. If we were inside the function then we would get the function context

Lets take another example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}
person.getName()();

Now in this case getName() is returning the function, so what would be the output, it would be person object, because it getName() is function and that is the context that we are working with and because we are returning the function, so this will be set to the context of invoice object.

Another important aspect for arrow functions is related to .bind, .call and .apply. Consider following example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}

var person2 = {
    age: 36,
    firstName: "john",
    lastName: "doe",

}
person.getName().bind(person2)();

Output will be {age: 34, firstName: “aamol”, lastName: “gote”} and not person2 object. This is very important with arrow functions you cannot bind a new object to arrow functions. Javascript engine did not even throw the error, it just ignored the bind call. So when u are working with arrow functions you will not be able to change the value of this like in traditional javascript.

Like .bind similar scenario exist for .call and .apply.

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: function(){
        return () => console.log(this)
    }
}

var person2 = {
    age: 36,
    firstName: "john",
    lastName: "doe",

}
person.getName().call(person2);

Output will be {age: 34, firstName: “aamol”, lastName: “gote”} and not person2

Same applies to .apply.

So in summary in case of arrow function .call, .bind and .apply are useless, you cannot change the value of this.

One more quirk to the arrow functions consider the following example

'use strict'
var person = {
    age: 34,
    firstName: "aamol",
    lastName: "gote",
    getName: () 
        => console.log(this)
    
}
person.getName();

This is gives an syntax error “Uncaught SyntaxError: Unexpected token =>”
New line character is problem with arrow functions you cannot put the arrow symbol on to the new line.

Arrow functions do not have “prototype” property.

'use strict'
var getName = () => "aamol";
console.log(getName.hasOwnProperty("prototype"));

Output would be false.

Whenever you declare a function in javascript it will by default have the prototype property. So unlike ES% in ES6 if you declare an function with arrow symbol, we do not have access to prototype.

Signal R Load balancing Issue

If you are using Signal R and and Signal R Hub as part of an ASP.net application which sits behind the loadbalancer with more than one machine then there is possiblity that you will start seeing this below error

SignalR – The connection id is in the incorrect format.

Just like when load balancing an ASP.NET website that uses Session, SignalR instances which are load balanced requires that all servers which handle SignalR requests must share a machine key. This is not mentioned in any documentation for SignalR/. ConnectionToken is encrypted using the machine key, when an application hits server 1 it is assigned a connectionToken generated using that machine’s machine key. If the application then hits server 2 with that assigned connectionToken, machine 2 cannot decrypt the token unless is has a matching machine key.

To solve this issue in your application web.config file you can add the machine key configuration

    
    <machineKey decryptionKey="EF1E7D088734F1B53F6594DE015FA9950B1379E4F2C3261E"
                validationKey="26EAACEB1553F966A8EC1B0304131B9D63CB81970B9204A04380189E040A84C0DC97303552434261E9445434392413EF881CF54892851955461A826805A78AA0" />

Now you must be wondering how can generate these keys, IIS manager helps you to generate those keys

  • Open IIS Manager, host you are application website on the IIS, click on the site, then on the Features view tab, select machine key as shown below
    machinekey
  • After selecting machine keys you will see following default options MachineKey1.jpg
  • Uncheck all the checkboxes and on the right side tab click on the “Generate Keys” option. machinekey2
  • Post generating the keys, Click on apply, this will add the machine key configuration web site web.config file as shown above.

Observable’s in Angular 2 (RxJS)

Observables in Angular 2 can be achieved using RxJS(Reactive Extensions for JavaScript). Observables is an ES7 feature so you need to make use of an external library to use it today. RxJS is a library that allows you to work with asynchronous data streams. So what are asynchronous data streams?

  • Asynchronous – we can call a function and register a callback to be notified when results are available, so we can continue with execution and avoid the Web Page from being unresponsive. This is used for ajax calls, DOM-events, Promises, WebWorkers and WebSockets.
  • Data – raw information in the form of JavaScript data types as: Number, String, Objects (Arrays, Sets, Maps).
  • Streams – sequences of data made available over time. Technically everything is stream.

Observables can help manage async data and a few other useful patterns. Observables are similar to Promises but with a few key differences. The first is Observables emit multiple values over time. For example a Promise once called will always return one value or one error. This is great until you have multiple values over time. Web socket/real-time based data or event handlers can emit multiple values over any given time. This is where Observables really shine. Observables are used extensively in Angular 2.

 Observables  Promise
 Observables handle multiple values over time  Promises are only called once and will return a single value
 Observables are cancellable  Promises are not cancellable

The ability of observables being able to handle multiple values over time makes them a good candidate for working with real-time data, events and any sort of stream you can think of. Being able to cancel observables gives better control when working with in-flow of values from a stream. The common example is the auto-complete widget which sends a request for every key-stroke.

RxJS Observable Promise
Execution  Lazy Eager
Asynchronous  YES YES
Handles data sources that produce ONE value YES YES
Handles data sources that produce MULTIPLE values YES
Debouncing &

Throttling

YES NO
Can be cached YES NO
Can be cancelled YES NO
Retry from failure YES NO

RxJS also provides Observable operators which you can use to manipulate the data being emitted. Some of common operators are:

  • Map
  • Filter
  • Take
  • Skip
  • Debounce
  • Retry

So in angular 2 now you services will start returns observables instead of promises like shown below for category service, getCategories returns an observable.

import { Injectable, Inject } from '@angular/core';
import { Http, Response} from '@angular/http';
import { OpaqueToken } from '@angular/core';

import {Category} from './category';
import {Observable} from 'rxjs/Observable';


export let INTERVIEW_APP_CONFIG = new OpaqueToken('app.config');
export interface ApplicationConfiguration{
    apiEndPoint : string,
    timeOut: number
}

export const INTERVIEW_APP_DI_CONFIG: ApplicationConfiguration = {
  apiEndPoint: 'http://app.cloudapp.net/api/Category',
  timeOut: 20
};


@Injectable()
export class CategoryService {
    categoryServiceUrl :string;
    constructor(private http: Http, @Inject(INTERVIEW_APP_CONFIG) config: ApplicationConfiguration){
        console.log(config.apiEndPoint);
        this.categoryServiceUrl = config.apiEndPoint;
    }
       
    getCategories (): Observable<Category[]>{
        console.log("Get Categories");
        return this.http.get(this.categoryServiceUrl)
                        .map(this.extractCategoryData)
                        .catch(this.handleError);
                        
    } 
    
    private extractCategoryData(res: Response){
        let body = res.json();
        return body || { };
    }
    
    private handleError (error: any) {
        let errMsg = (error.message) ? error.message : 
        error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
  }
}

An observable is only enabled when a first observer subscribes. This is a significant difference compared to promises. As a matter of fact, processing provided to initialize a promise is always executed even if no listener is registered. This means that promises don’t wait for subscribers to be ready to receive and handle the response. When creating the promise, the initialization processing is always immediately called.

Observables are lazy so we have to subscribe a callback to let them execute their initialization callback. below component defines the subscribe for the observable which has been returned,

import { Component, OnInit } from '@angular/core';
import { Category } from './category';
import './rxjs-operators';
import { CategoryService, INTERVIEW_APP_CONFIG, INTERVIEW_APP_DI_CONFIG } from './categoryService';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
  providers:[CategoryService, { provide: INTERVIEW_APP_CONFIG, useValue: INTERVIEW_APP_DI_CONFIG }]
})
export class AppComponent {
  title = 'app works!';
  firstName="Aamol";
  errorMessage: string;
  categories: Category[];
  
 constructor(private categoryService: CategoryService){
   
 }
 ngOnInit(){
   this.getCategories();
   console.log("Getting categories");
  } 
 
 getCategories() {
   this.categoryService.getCategories()
                  .subscribe(
                    categories => this.categories = categories,
                    error => this.errorMessage = error
                  );
 }
}

Observables allow you to register callbacks as shown above, the subscribe method three callbacks as parameters:

  • The onNext callback that will be called when an event is triggered.
  • The onError callback that will be called when an error is thrown.
  • The onCompleted callback that will be called when the observable completes.

Here is the way to register callbacks on an observable:

categoryService.getCategories.subscribe(
  (event) => {
    // handle events
  },
  (error) => {
    // handle error
  },
  () => {
    // handle completion
  }
);

The observable class provides a fromPromise method to create an observable from a promise. This allows you to make a promise part of an asynchronous data stream

Retrying requests – Observable allows you to repeat the source observable sequence the specified number of times or until it successfully terminates. In the context of HTTP requests, this allows you to transparently re-execute requests that failed.

getCategories (): Observable<Category[]>{
        console.log("Get Categories");
        return this.http.get(this.categoryServiceUrl)
                        .retry(4)
                        .map(this.extractCategoryData)
                        .catch(this.handleError);
                        
    } 

Enable RxJS Operators – The RxJS library is quite large. So Angular 2 exposes a stripped down version of Observable in the rxjs/Observable module, a version that lacks most of the operators including map, retry which we have used above, it’s up to us to add the operators we need. We could add every RxJS operators with a single import statement. but we’d pay a penalty in extended launch time and application size because the full library is so big. We only use a few operators in our app.

Instead, we’ll import each Observable operator one-by-one, we’ll put the import statements in one app/rxjs-operators.ts file.

// Statics
import 'rxjs/add/observable/throw';

// Operators
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/retry';

Your API’s and HAL

HAL – Hypertext Application Language

HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API. Adopting HAL will make your API explorable, and its documentation easily discoverable from within the API itself. In short, it will make your API easier to work with and therefore more attractive to client developers.

APIs that adopt HAL can be easily served and consumed using open source libraries available for most major programming languages. It’s also simple enough that you can just deal with it as you would any other JSON. HAL provides a set of conventions for expressing hyperlinks in either JSON or XML. The rest of a HAL document is just plain old JSON or XML. Instead of using ad-hoc structures, or spending valuable time designing your own format; you can adopt HAL’s conventions and focus on building and documenting the data and transitions that make up your API. Its conventions make the documentation for an API discoverable from the API messages themselves. This makes it possible for developers to jump straight into a HAL-based API and explore its capabilities, without the cognitive overhead of having to map some out-of-band documentation onto their journey.

The HAL conventions revolve around representing two simple concepts: Resources and Links.

Resources have: Links (to URIs), Embedded Resources (i.e. other resources contained within them), State (your standard JSON or XML data).

Links have: A target (a URI), A relation aka. ‘rel’ (the name of the link), a few other optional properties to help with deprecation, content negotiation, etc.

HAL is designed for building APIs in which clients navigate around the resources by following links. Links are identified by link relations. Link relations are the lifeblood of a hypermedia API: they are how you tell client developers about what resources are available and how they can be interacted with, and they are how the code they write will select which link to traverse.

@Injectables + Angular 2.0 + @Inject

@Injectable() is the decorator in Angular 2.0

Typically in Angular 2.0 services are simple classes and if these services require dependencies to be injected then you need this decorator.

DI (Dependency Injection) in Angular 2.0 is hierarchical in nature, for dependency injection to be able to create instances for you, you need to register providers for these classes (or other values) somewhere. and you can configure providers for DI at different levels

  • For the whole application when bootstrapping it. In this cases, all sub injectors (the component ones) will see this provider and share the instance associated with. When interacting, it will be the same instance
  • For a specific component and its sub components. Same as before but for à specific component. Other components won’t see this provider. If you redefine something defined above (when bootstrapping for example), this provider will be used instead. So you can override things. If a provider is registered in one of the child components a new (different) instance is provided for descendants of this component.
  • If a component requests an instance (by a constructor parameter), DI looks “upwards” the component tree (starting from leaf towards the root) and takes the first provider it finds. If an instance for this provider was already created previously, this instance is used, otherwise a new instance is created.

Angular 2.0 docs recommend adding @Injectable() to all services classes , even those that don’t have dependencies and, therefore, do not technically require it. Here’s why:

  • Future proofing: No need to remember @Injectable() when we add a dependency later.
  • Consistency: All services follow the same rules, and we don’t have to wonder why a decorator is missing.

Here is sample service (CategoryService) for my mobile app

import { Injectable } from '@angular/core';
import { Http, Response} from '@angular/http';

import {Category} from './category';
import {Observable} from 'rxjs/Observable';

@Injectable()
export class CategoryService {
    constructor(private http: Http){
        
    }
    
    private categoryServiceUrl = "http://app.cloudapp.net/api/Category";
    
    getCategories (): Observable<Category[]>{
        return this.http.get(this.categoryServiceUrl)
                        .map(this.extractCategoryData)
                        .catch(this.handleError);
                        
    } 
    
    private extractCategoryData(res: Response){
        let body = res.json();
        return body || { };
    }
    
    private handleError (error: any) {
        let errMsg = (error.message) ? error.message : 
        error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); 
        return Observable.throw(errMsg);
  }
}

 

Here is how you register with provider this is at component level

import { Component, OnInit } from '@angular/core';
import { Category } from './category';
import { CategoryService } from './categoryService';
// Add the RxJS Observable operators we need in this app.
import './rxjs-operators';
@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  providers:[CategoryService]
})
export class AppComponent implements OnInit{
  title = 'app works!';
  firstName= "Aamol Gote";
  errorMessage: string;
  categories: Category[];
  
  constructor(private categoryService: CategoryService){
    
  }
  
  ngOnInit() {
    this.getCategories();
  }
  
  getCategories(){
    this.categoryService.getCategories()
                        .subscribe(
                          categories => this.categories = categories,
                          error => this.errorMessage = <any>error
                        );
  }
}

 

@Inject – This is manual way of letting angular know that this parameter must be injected. typically DI is implicit in nature for Angular 2.0 but for certain edge cases if there is need to specify dependency explicitly with its type then @Inject is used. One very good candidate for @Inject is for injecting non class dependencies. Suppose if you have an application configuration which includes API end point, then these configurations need not necessarily be instances of the classes these can be just object literals, for e.g. as shown below

export interface ApplicationConfiguration{
    apiEndPoint : string,
    timeOut: number
}

export const INTERVIEW_APP_CONFIG: ApplicationConfiguration = {
  apiEndPoint: 'http://app.cloudapp.net/api/Category',
  timeOut: 20
};

 

Now we need to inject INTERVIEW_APP_CONFIG in CategoryService, way we do it first need to register the Provider for INTERVIEW_APP_CONFIG,

[{ provide: InterviewAppConfig, useValue: INTERVIEW_APP_CONFIG  })]

constructor(private config:InterviewAppConfig){ }

 

But the above code snippet fails as INTERVIEW_APP_CONFIG constant has an interface, InterviewAppConfig. We cannot use a TypeScript interface as a token, to solve this we have to use Opaque tokens, here is the updated category service class with config value injected through @Inject()

import { Injectable, Inject } from '@angular/core';
import { Http, Response} from '@angular/http';
import { OpaqueToken } from '@angular/core';

import {Category} from './category';
import {Observable} from 'rxjs/Observable';

export let INTERVIEW_APP_CONFIG = new OpaqueToken('app.config');
export interface ApplicationConfiguration{
    apiEndPoint : string,
    timeOut: number
}

export const INTERVIEW_APP_DI_CONFIG: ApplicationConfiguration = {
  apiEndPoint: 'http://app.cloudapp.net/api/Category',
  timeOut: 20
};


@Injectable()
export class CategoryService {
    categoryServiceUrl :string;
    constructor(private http: Http, @Inject(INTERVIEW_APP_CONFIG) 
        config: ApplicationConfiguration){
        this.categoryServiceUrl = config.apiEndPoint;
    }
    
    
    
    getCategories (): Observable<Category[]>{
        console.log("Get Categories");
        return this.http.get(this.categoryServiceUrl)
                        .map(this.extractCategoryData)
                        .catch(this.handleError);
                        
    } 
    
    private extractCategoryData(res: Response){
        let body = res.json();
        return body || { };
    }
    
    private handleError (error: any) {
        let errMsg = (error.message) ? error.message : 
        error.status ? `${error.status} - ${error.statusText}` : 'Server error';
        console.error(errMsg); // log to console instead
        return Observable.throw(errMsg);
  }
}

 

We need register the provider in the component like shown below

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css'],
  providers:[CategoryService, { provide: INTERVIEW_APP_CONFIG, 
                                useValue: INTERVIEW_APP_DI_CONFIG }]
})