Exploring Angular Services

Deep Gautam  Print 
11 Oct 2018
 
Intermediate
166

Services in Angular is meant for specifically making the call to RestFul API and getting the data and passing data to all component which ever component subscribe it. Moreover it gives us the benefit of code reusability and data sharing across components.

Goals

  1. How to create a basic service in Angular

  2. How to subscribe the service response.

  3. How to handle error in service.

Specifications

In this tutorial , we will create a basic angular application and try to use service to get data and pass the data component.

Why Services

Basically component is meant for providing the data to view, when I say view means providing the data to respective HTML whatever is required, it is not a good practice to make a api call directly from component. Services gives the benefit of separation of concerns and you can say single responsibility principle as well.

Let see services in action

  1. Create angular project :go to VS code integrated terminal

     
    Run - ng new ServiesTest
    
  2. Run this newly created project by using below command

    ng serve
    

    Once you run this command you must see below page at http://localhost:4200/

  3. Create a service by using below command

    ng g s DateTime
    
  4. Now go to DateTimeService.ts file you will find below code

    import { Injectable } from '@angular/core';
    
    @Injectable({
     providedIn: 'root'
    })
    export class DateTimeService {
    
     constructor() { }
    }
    

    If you notice it has the @Injectable decorator similar to @Component decorator what we use to have in a angular component. @Injectable means it can participate in dependency injection, those who don't know dependency injection I will explain it in my next article as it is not the topic of this discussion, it need further explanation, so will keep that in separate article.@Injectable accepts metadata object. So here you can providedIn value as root , which means this service can be injected in any of the class across the project.

  5. Now let us write the code to consume actual service.So here I am trying to call a real-time RestFul API which is fromhttps://www.jsontest.com/

  6. We will call a API located at : http://date.jsontest.com So here is the code for same :

    import { Injectable } from '@angular/core';
    
    @Injectable({
     providedIn: 'root'
    })
    export class DateTimeService {
    
     public apiURL:string="http://date.jsontest.com";
     constructor() { }
    
     getDateTime ()
     {
     return this.httpClient.get(this.apiURL)
     .pipe(
     map(res => res),
     catchError( this.errorHandler)
     );
     }
    
    }
    

    So my code is complaining about httpClient, map, catchError, and errorHandler.

  7. So let us do import for these complain.

     
    import { HttpClient } from '@angular/common/http';
     

    For httpClient and inject in constructor like below :

    constructor(private httpClient:HttpClient) { }
    import { map, catchError } from 'rxjs/operators';
    For map, catchError 
    Now it's time to fix errorHandler.
    So write one method like below:
    
    errorHandler(error: Response) { 
     console.log(error); 
     return throwError(error); 
    }
    

    Lastly do this import :

    import {throwError} from 'rxjs'
    

    So finally service code looks like this :

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import {throwError} from 'rxjs'
    import { map, catchError } from 'rxjs/operators';
    
    @Injectable({
     providedIn: 'root'
    })
    export class DateTimeService {
    
     public apiURL:string="http://date.jsontest.com";
     constructor(private httpClient:HttpClient) { }
    
     getDateTime ()
     {
     return this.httpClient.get(this.apiURL)
     .pipe(
     map(res => res),
     catchError( this.errorHandler)
     );
     }
     errorHandler(error: Response) { 
     console.log(error); 
     return throwError(error); 
    } 
    }
    

    If any error while calling the service it will be logged in console and error will thrown to the subscriber.Now it is the time to consume this service from the component.So here you go.

    Go to app.module.ts and import
    import { HttpClient,HttpClientModule } from '@angular/common/http';
    

    Use this import in import array like this

     imports: [
     BrowserModule,HttpClientModule
     ],
    

    First of all you need to inject this service in component like this :

    constructor(private dateTimeService:DateTimeService){}
    

    So here now by using this dateTimeService injector we will call the service method like this

    ngOnInit()
     {
     this.dateTimeService.getDateTime()
     .subscribe((result) => {
     this.globalResponse = result; 
     },
     error => { //This is error part
     console.log(error.message);
     },
     () => {
     // This is Success part
     console.log("Date time fetched sucssesfully.");
     console.log(this.globalResponse);
     }
     )
    
     }
    

    Here we are calling getDateTime method from service , which will call http://date.jsontest.com and return us back output in below format.

    {
     "time": "03:53:25 AM",
     "milliseconds_since_epoch": 1362196405309,
     "date": "03-02-2013"
    }
    

    We are subscribing the service response here in component, similarly in this way you can consume this service in any of your component because service is injected in root. So in my component, as you can see I am storing the service response in global response. Since we have logged the service response in console , so you can see response in console something like this.

    Let us bind this variable to HTML. Go to app.component.html and paste this code :

     <div style="text-align:center">
     <h1>
     Welcome to {{ title }}!
     </h1>
     <h2>Current date {{globalResponse.date}}</h2>
     <h2>Current Time {{globalResponse.time}}</h2>
     </div>
    

    And run the project , your output will be like this

    Now let me give all required files source code :

    App.module.ts
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { HttpClient,HttpClientModule } from '@angular/common/http';
    
    import { AppComponent } from './app.component';
    
    @NgModule({
     declarations: [
     AppComponent
     ],
     imports: [
     BrowserModule,HttpClientModule
     ],
     providers: [],
     bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    
    date-time.service.ts:
    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import {throwError} from 'rxjs'
    import { map, catchError } from 'rxjs/operators';
    
    @Injectable({
     providedIn: 'root'
    })
    export class DateTimeService {
    
     public apiURL:string="http://date.jsontest.com";
     constructor(private httpClient:HttpClient) { }
    
     getDateTime ()
     {
     return this.httpClient.get(this.apiURL)
     .pipe(
     map(res =>res),
     catchError( this.errorHandler)
     );
     }
     errorHandler(error: Response) { 
     console.log(error); 
     return throwError(error); 
    }
    }
    
    app.component.ts
    import { Component,OnInit } from '@angular/core';
    import { DateTimeService } from './date-time.service';
    
    @Component({
     selector: 'app-root',
     templateUrl: './app.component.html',
     styleUrls: ['./app.component.css']
    })
    export class AppComponent implements OnInit {
     title = 'DotNet Techy YouTube Channel Services in Angular 6 Demo';
     public globalResponse: any;
     constructor(private dateTimeService:DateTimeService){}
    
     ngOnInit()
     {
     this.dateTimeService.getDateTime()
     .subscribe((result) => {
     this.globalResponse = result; 
     },
     error => { //This is error part
     console.log(error.message);
     },
     () => {
     // This is Success part
     console.log("Date time fetched sucssesfully.");
     console.log(this.globalResponse);
     console.log("Thanks to DotNet Techy Youtube channel who taught me, how to create services in Angular 6.");
     }
     )
    
     }
     }
    
    app.component.html
    <div style="text-align:center">
     <h1>
     Welcome to {{ title }}!
     </h1>
     <h2>Current date {{globalResponse.date}}</h2>
     <h2>Current Time {{globalResponse.time}}</h2>
    </div>
    
Summary

Similarly you can use post, put,delete as well. It is so simple, if any doubt comment on article I will help you on that.

Hands-on Learning
Free Interview Books
 
+