Tuesday, 21 November 2017

HTTP Requests with Observables- Angular 2

Making HTTP requests is a vital operation in the life of most front-end applications. Angular 2, which is the hottest thing right now has a really cool way of doing that. Actually that is what we are going to cover together today in this tutorial. We will learn how how to make HTTP requests using RxJs Observable library.

What are Observables?
Observables are similar to promises but with major differences that make them better. The key differences are:

ObservablesPromise
Observables handle multiple values over timePromises are only called once and
will return a single value
Observables are cancellablePromises 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.

If you are searching for angular in an auto-complete, the first request is with a and then an. The scary thing is that an might come back with a response before a which produces a messy data. With observables, you have better control to hook in and cancel a's because an is coming through.

Observables is an ES7 feature which means you need to make use of an external library to use it today. RxJS is a good one. RxJS also provides Observable operators which you can use to manipulate the data being emitted. Some of these operators are:
Map
Filter
Take
Skip
Debounce
Above is a list of popular operators you will encounter in most projects but those are not all.
Meet the Angular 2 HTTP Service

The service class has the following structure:
Product.service.cs

import { Product } from '../../models/product';
import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { environment as env } from '../../../environments/environment';
import { AuthService } from '../../services/auth.service';

@Injectable()
export class ProductService {
  private baseUrl = '';
  private headers: any;
  private options;

  constructor(private http: Http, private authService: AuthService) {
    // this.headers = new Headers({ 'Content-Type': 'application/json' });
    this.options = new RequestOptions({ headers: new Headers({ 'authorization': this.authService.user.token,
     'Content-Type': 'application/json' }) });
    this.baseUrl = env.apiAddress;
  }

  getAll(): Observable<Product[]> {
    return this.http.get(`${this.baseUrl}/product`, this.options)
     .map((res: Response) => res.json())
     .catch((error: any) => Observable.throw(error.json().error || 'Server error'));
  }

  get(id: string): Observable<Product> {
    return this.http
      .get(`${this.baseUrl}/product/${id}`, this.options)
      .map((res: Response) => {
        return res.json();
      })
      .catch((error: any) => Observable.throw('Server error'));
  }

  add(product: Product): Observable<Response> {

    return this.http
      .post(`${this.baseUrl}/product`, JSON.stringify(product), this.options)
      .catch((error: any) => Observable.throw('Server error'));
  }

  update(product: Product): Observable<Response> {
    return this.http
 .put(`${this.baseUrl}/product/${product._id}`, JSON.stringify(product), { headers: this.headers })
      .catch((error: any) => Observable.throw('Server error'));
  }

  delete(id: string): Observable<Response> {
    return this.http
      .delete(`${this.baseUrl}/product/${id}`)
      .map((res: Response) => {
        return res;
      })
      .catch((error: any) => Observable.throw('Server error'));
  }
}

We have imported the required libraries for our service to behave as expected. Notice that the observable we spoke about has also been imported and used. The map and catch observable operators which will help us to manipulate data and handle errors respectively has also been imported. Then we inject HTTP in the constructor and keep a reference to the base url of our API.

With the map operator, we call the .json method on the response because the actual response is not a collection of data but a JSON string.

NOTE: Angular 4.3 uses JSON response by default. Therefore, you can get rid of that line if you are using the latest version of Angular.


0 comments:

Post a Comment

Topics

ADO .Net (2) Ajax (1) Angular Js (17) Angular2 (24) ASP .Net (14) Azure (1) Breeze.js (1) C# (49) CloudComputing (1) CMS (1) CSS (2) Design_Pattern (3) DI (3) Dotnet (21) Entity Framework (3) ExpressJS (4) Html (3) IIS (1) Javascript (6) Jquery (9) Lamda (3) Linq (11) Mongodb (1) MVC (48) NodeJS (7) RDLC (1) Report (1) Sql Server (29) SSIS (3) SSRS (2) UI (1) WCF (12) Web Api (10) Web Service (1) XMl (1)