Monday, 24 October 2016

Send a HTTP request in angular2 Service using Typescript

In this post we are going to see how to send a HTTP request in Angular2 service and access the data from the response using the observable API







   

First we have to create a Model based on the response type, so that we are creating a interface for that, then we have to create a service which will make a HTTP call.



export interface IUser{
    id:number;
    name:string;
    username:string;
    email:string;
    address:IAddress;
    phone:string;
    website:string;
    company:ICompany;
    albums:IAlbum[];    
}

export interface ICompany{
    name:string;
    catchPharse:string;
    bs:string;
}

export interface IAddress{
    street:string;
    suite:string;
    city:string;
    zipcode:string;
    geo:IGeo;
}

export interface IGeo{
    lat:string;
    lon:string;
}

export interface IAlbum{
    albumId:number;
    id:number;
    title:string;
    url:string;
    thumbnailUrl:string;
}


Then we have to create a service which have the HTTP api has a dependency , The instance of the HTTP will be created in the constructor.



    import { Injectable } from '@angular/core';
    import { Http, Response } from '@angular/http';
    import { Observable } from 'rxjs/observable';
    import { IUser,IAlbum } from './user';
    import 'rxjs/add/operator/catch'
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/do';

    @Injectable()
    export class DataService{

    private data:string[]=["Rajesh","suresh","ramu"];
    private url:string = "http://jsonplaceholder.typicode.com/users";

    constructor(private _http:Http){

    }

    getEmployees(): Observable<IUser[]>{
    return this._http.get(this.url)
    .map((response:Response)=><IUser[]>response.json())
    .do(data=>console.log("All : "+JSON.stringify(data)))
    .catch(this.HandleError);
    }

    getAlbums(id):Observable<any>{

    return this._http.get("http://jsonplaceholder.typicode.com/photos?albumId="+id)
    .map((response:Response)=><IAlbum[]>response.json())
    .do(data=>console.log("album "+JSON.stringify(data)))
    .catch(this.HandleError);       

    }


    private HandleError(error:Response){
        console.log(error);
        return Observable.throw(error.json().error || "server error");
    }

    addEmployee(name){
        this.data.push(name);
    }

    }




Next we have to invoke the call from inside the component , here we have to subscribe the request because return type of the method is a observable of particular type, in observable to get the response we have to subscribe , in subscribe we have three parameter, success, error, complete.






import { Component } from '@angular/core';
import { DataService } from './data.service';
import { IUser } from './user'

@Component({
    selector:'employee',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Employee </h1>
        <div>
            <input type="text" #emp />
            <button (click)="addEmployee(emp.value)" 
                class="btn btn-sm btn-primary">Add Emp</button>
            <button (click)="getEmployee()" 
                class="btn btn-sm btn-primary">Get Employees</button>
            <div style="margin-top:20px">
            <ul class="list-group" style="display:-webkit-box;overflow-x:scroll">
                <li class="panel list-group-item-primary" 
                *ngFor="let e of employees" style="list-style:none;">
                <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">{{e.username}}</h3>
                </div>
                <div class=""panel-body>
                    <div class="text-info" style="padding:5px;">{{e.name}} 
                    <span class="btn btn-sm btn-primary" 
                        (click)="getAlbum(e.id)">Get Album</span></div>
                    <div class="text-primary" style="padding:5px;"> 
                        {{e.address.city}},{{e.address.zipcode}}</div>
                    <div *ngIf="e.albums">
                    <ul class="list-group">
                    <li class="list-group-item" *ngFor="let alb of e.albums">
                        <div class="panel panel-default">
                            <div class="panel-heading">{{alb.title}}</div>
                            <div class=""panel-body>                       
                                <img [src]="alb.thumbnailUrl" />
                            </div>
                        </div>
                    </li>
                    </ul>
                    </div>
                </div>
                </div>
                </li>
            </ul>
            </div>
        </div>
    </div>
    `   
})
export class EmployeeComponent
{
    employees:IUser[];
  
    constructor(private dataservice:DataService){
        
    }

    addEmployee(employeeName)
    {
        this.dataservice.addEmployee(employeeName);
    }

    getEmployee(){
        this.dataservice.getEmployees()
        .subscribe(
            customer=>this.employees=customer,
            error=>console.log("error"+error)
            );
       
    }

    getAlbum(id){
        this.dataservice.getAlbums(id)
        .subscribe(
            albums=>this.employees.find(emp=>emp.id==id).albums = albums
            );
    }
}



Next thing we have to inject the module in to root module then start the app to run


    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { HttpModule } from '@angular/http';
    
    import { BaseRequestOptions, Http, Headers } from '@angular/http';
    import { webformComponent } from './Component/web.component'
    import { PrintComponent } from './Component/print.component';
   
    import { EmployeeComponent,StudentComponent } from './employee.component'
    import { DataService } from './data.service';

    @NgModule({
        imports: [BrowserModule,
                  FormsModule,
                  HttpModule],
        exports: [],
        declarations: [webformComponent,
                       PrintComponent,        
                       EmployeeComponent],
        providers:[DataService],
        bootstrap:[webformComponent]
    })
    export class AppModule { 

    }




    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    import { AppModule } from './app.module';
    import { HelloModule } from './hello.module'

    const platform = platformBrowserDynamic();

    let moduleref = platform.bootstrapModule(AppModule);







Output:
********************











When you click on the Get Employees, it will fetch the information














When user click on the Get Album for each user this will fetch the album info










From this post you can learn how to invoke a Http call from the angular2 service







Tuesday, 11 October 2016

Create a service in angular2 and inject it in to Components by Dependency injection

In this post we are going to see how to create a service in Angular2 application and inject it in to Component by Dependency injection. For this we are going to create a sample employee service  and inject it in to two components , for this we are going to create two components Employee and Student Component, But there is a issue in this if we are injecting service in to two components individually, then the new instance are created independently for this two service, so the data wont share or change wont reflect in other component



Creating a Service:

import { Injectable } from '@angular/core';

@Injectable()
export class DataService{

private data:string[]=["Rajesh","suresh","ramu"];

getEmployees(){
    return this.data;
}

addEmployee(name){
    this.data.push(name);
}

}





Inject Service independently in Component:

   In this we are injecting service in to the components using providers in there Component decorators directly, so what will happen his it will create a new instance , because of this each and every component will use the separate instance, nothing will be shared across the components

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
    selector:'employee',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Employee </h1>
        <div>
            <input type="text" #emp />
            <button (click)="addEmployee(emp.value)" 
                    class="btn btn-sm btn-primary">Add Emp</button>
            <button (click)="getEmployee()" 
                    class="btn btn-sm btn-primary">Get Employees</button>
            <div>
                <ul class="list-group">
                    <li class="panel list-group-item-primary" 
                        *ngFor="let e of employees" style="list-style:none;">
                        {{e}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
    `,
    providers:[DataService]
})
export class EmployeeComponent
{
    employees:string[];

    constructor(private dataservice:DataService){
        
    }

    addEmployee(employeeName)
    {
        this.dataservice.addEmployee(employeeName);
    }

    getEmployee(){
        this.employees = this.dataservice.getEmployees();
    }
}


@Component({
    selector:'student',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Student </h1>
        <div>
            <input type="text" #std />
            <button (click)="addStudent(std.value)" 
                    class="btn btn-sm btn-primary">Add Student</button>
            <button (click)="getStudents()" 
                     class="btn btn-sm btn-primary">Get Students</button>
            <div>
                <ul class="list-group">
                    <li class="panel list-group-item-primary" 
                        *ngFor="let s of students" style="list-style:none;">
                        {{s}}
                    </li>
                </ul>
            </div>
        </div>
        </div>
    `,
    providers:[DataService]
})
export class StudentComponent
{
    students:string[];

    constructor(private dataservice:DataService){
        
    }

    addStudent(studentName)
    {
        this.dataservice.addEmployee(studentName);
    }

    getStudents(){
        this.students = this.dataservice.getEmployees();
    }
}




Module.ts:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { BaseRequestOptions, Http, Headers } from '@angular/http';
    import { webformComponent } from './Component/web.component'  
    import { EmployeeComponent,StudentComponent } from './employee.component'
    import { DataService } from './data.service';

    @NgModule({
        imports: [BrowserModule,FormsModule],
        exports: [],
        declarations: [webformComponent,EmployeeComponent,StudentComponent],       
        bootstrap:[webformComponent]
    })
    export class AppModule { 

    }


In module we can see the change in both the types

For ex:
In above Example we can see that the element add in the Employee doesn't reflect in Student


Output:

















Inject Service Globally for all component:

  In this we are injecting service in to the module using providers in module decorator directly, so what will happen his it will create a new instance , because of this each and every component will use the same instance, everything will be shared across the components

import { Component } from '@angular/core';
import { DataService } from './data.service';

@Component({
    selector:'employee',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Employee </h1>
        <div>
            <input type="text" #emp />
            <button (click)="addEmployee(emp.value)" 
                    class="btn btn-sm btn-primary">Add Emp</button>
            <button (click)="getEmployee()" 
                    class="btn btn-sm btn-primary">Get Employees</button>
            <div>
                <ul class="list-group">
                    <li class="panel list-group-item-primary" 
                        *ngFor="let e of employees" style="list-style:none;">
                        {{e}}
                    </li>
                </ul>
            </div>
        </div>
    </div>
    `
})
export class EmployeeComponent
{
    employees:string[];

    constructor(private dataservice:DataService){
        
    }

    addEmployee(employeeName)
    {
        this.dataservice.addEmployee(employeeName);
    }

    getEmployee(){
        this.employees = this.dataservice.getEmployees();
    }
}


@Component({
    selector:'student',
    template:`
    <div style="display:inline-block;width:400px;vertical-align:top">
        <h1>Student </h1>
        <div>
            <input type="text" #std />
            <button (click)="addStudent(std.value)" 
                    class="btn btn-sm btn-primary">Add Student</button>
            <button (click)="getStudents()" 
                     class="btn btn-sm btn-primary">Get Students</button>
            <div>
                <ul class="list-group">
                    <li class="panel list-group-item-primary" 
                        *ngFor="let s of students" style="list-style:none;">
                        {{s}}
                    </li>
                </ul>
            </div>
        </div>
        </div>
    `
})
export class StudentComponent
{
    students:string[];

    constructor(private dataservice:DataService){
        
    }

    addStudent(studentName)
    {
        this.dataservice.addEmployee(studentName);
    }

    getStudents(){
        this.students = this.dataservice.getEmployees();
    }
}





Module.ts:

In this we can see that the Providers is injected in to module directly to use it across the components.

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { FormsModule } from '@angular/forms';
    import { BaseRequestOptions, Http, Headers } from '@angular/http';
    import { webformComponent } from './Component/web.component'  
    import { EmployeeComponent,StudentComponent } from './employee.component'
    import { DataService } from './data.service';

    @NgModule({
        imports: [BrowserModule,FormsModule],
        exports: [],
        declarations: [webformComponent,EmployeeComponent,StudentComponent],
        providers:[DataService],
        bootstrap:[webformComponent]
    })
    export class AppModule { 

    }


For ex:
In above Example we can see that the element add in the Employee reflect in Student



Output:









 







Main Component to Bootstrap:

import { Component,ViewEncapsulation,Input,Output } from '@angular/core';


@Component({
    selector:'webform',
    template:`
    <form>    
       <student></student> 
       <employee></employee>      
    </form>`,
    styles:[`
        
    .input{        
        border: 1px solid #ddd;
        -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
        box-shadow: inset 0 1px 2px rgba(0,0,0,.07);
        background-color: #fff;
        color: #32373c;
        outline: 0;
        -webkit-transition: 50ms border-color ease-in-out;
        transition: 50ms border-color ease-in-out;
    }

    `],
    encapsulation:ViewEncapsulation.None
})
export class webformComponent{

    constructor(){

    }

}







index.html:

<body>
    <webform>Loading...</webform>
  </body>






From above post you learn how to inject the service in to the components in Angular2 applications