Home  > Resources  > Blog

What is HTTP Client in Angular?

 
November 17, 2020 by Bibhas Bhattacharya
Category: Angular

This tutorial is adapted from Web Age course Comprehensive Angular 10 Programming Training.

1.1 The Angular HTTP Client

The Angular HTTP Client provides a simplified API for network communication. It is a wrapper over the JavaScript XMLHttpRequest API. The API is asynchronous. JavaScript is single-threaded. Doing a blocking synchronous HTTP call will otherwise freeze the UI. It supports making HTTP requests (GET, POST, etc.), working with request and response headers, asynchronous programming. It makes use of the rxjs async library Observable object.

1.2 Using The HTTP Client – Overview

The core client API is available from the HttpClient Angular service class. This is available from the HttpClientModule Angular module.

  • Import HttpClientModule from your application module.

A Data Service is created that makes network requests:

  • Inject the HttpClient service instance.
  • Use various methods of HttpClient to make network calls. They return an Observable object. Usually, this Observable is returned from the service method.

An Angular component is used to display the response data:

    • The data service is injected into the constructor
    • The component calls a method of the data service and obtains an Observable object.
    • The component then “subscribes” to the Observable to receive the response from the HTTP call.
    • The component’s template displays the data

1.3 Importing HttpClientModule

In order to use the Http client throughout the application, we need to import HttpClientModule in the application module. HttpClientModule is a collection of service providers from the Angular HTTP library

import {HttpClientModule} from '@angular/common/http';
@NgModule({
    imports: [ BrowserModule, HttpClientModule ],
...})

Now the HttpClient service is injectable throughout your application

Importing HttpClientModule

Note that HttpClientModule configures HttpClient as a provider. You don’t have to do this again from your application module. As a result, HttpClient is now injectable anywhere in your application.

1.4 Service Using HttpClient

Sample Service Code (“people.service.ts”):

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export class Person {id:number, name:string ...}
@Injectable(...)
export class PeopleService{
  constructor(private http: HttpClient){}
  getPerson(id:number) : Observable<Person> {
   return this.http.get<Person>(`/app/person/${id}`)
  }
  getAllPersons() : Observable<Person[]> {
   return http.get<Person[]>(`/app/person`)
  }
}

1.5 Making a GET Request

  • Call the get() method of HttpClient service.
      All network call methods like get(), post(), put() return an Observable.
  • There are many overloaded versions of the get() call. Some are:
let obs:Observable<Object> = http.get(url) 
//Strong typing
let obs:Observable<Person> = http.get<Person>(url) 
  • For the get() calls it is recommended you use the strongly typed version (second one from above).
  • The get() method returns an Observable immediately. One needs to subscribe to the Observable to obtain the response data asynchronously.

Notes:

As they are used with the Angular HttpClient object Observable objects can be thought of as the glue that connects network requests with data consumers. There are several aspects to this relationship that our discussion will cover one at a time. From the current slide, we see that http requests return Observable objects that we can assign to a variable for later use. In the next slide, we will take a look at how Observable objects are used.

1.6 What does an Observable Object do?

Angular uses the Reactive Extensions for JavaScript (RxJS) implementation of the Observable object. Observable objects provide a convenient way for applications to consume asynchronous data/event streams. Observable objects are exposed to events which they then make available to consumers. Applications consume events by subscribing to the Observable object. The Observable object can be used to transform data before returning it to a consumer if needed.

  • Notes:

Reactive programming and Observable objects can be used anywhere an asynchronous programming model is required. For more information on these topics see:

http://reactivex.io/intro.html

1.7 Using the Service in a Component

  • Once the service has been created we can create an Angular component that uses it to retrieve and display data.
  • Our component will have to import the service.
  • In order to retrieve data, the code in our component will have to work with the Observable object that was created in the service.
  • The screenshot at the right shows how the data will look when displayed.

1.8 The PeopleService Client Component

import { Component, OnInit } from '@angular/core';
import { PeopleService, Person } from './people.service';
@Component({
  selector: 'app-people',
  template: `
    <p *ngFor='let person of list' >{person.name}}</p>`
})
export class PeopleComponent implements OnInit {
  list: Person[]
  constructor(private peopleService: PeopleService ){}
  ngOnInit() {
    this.peopleService.getAllPersons().subscribe(
      (data: Person[]) => this.list = data
    )
  }
}}

1.9 Error Handling

  • Two types of errors can happen during a network call:
    • No network connection can be made to the server.
    • The server returns an invalid response code in 4XX and 5XX range.
  • A subscriber can handle these errors by supplying an error handler function to subscribe().
ngOnInit() {
  this.peopleService.getAllPersons().subscribe(
    (data: Person[]) => this.list = data,
    (error:HttpErrorResponse) => console.log(error)
    )
}

1.10 Customizing the Error Object

    • A service may decide to offer more meaningful errors in a custom error object instead of the default HttpErrorResponse. You can intercept an error with the

catchError()

    • operator and supply a custom error object using

throwError()

    • .

The following transforms the error object from HttpErrorResponse to a string.

import {Observable, throwError} from 'rxjs'
import {catchError} from 'rxjs/operators'
export class PeopleService {
  constructor(httpClient: HttpClient){}
  getAllPersons() : Observable<Person[]> {
   return httpClient
    .get<Person[]>(`/app/person`)
    .pipe(
      catchError(error => 
        throwError("There was a problem with the network"))
    )
  }
}
//The component
ngOnInit() {
  this.peopleService.getAllPersons().subscribe(
    (data: Person[]) => this.list = data,
    (errMsg:string) => alert(errMsg))
}

1.11 Making a POST Request

Supply the request body as the second argument to the post() method.

createPerson(person:Person) : Observable {
  return this.http.post("/app/person", person) 
}

If a POST request returns data in the response body, you can make a more type-safe call.

createPerson(person:Person) : Observable<AddPersonResult> {
  return this.http.post<AddPersonResult>("/app/person", 
    person) 
}
//The component
this.peopleService.createPerson(...)
  .subscribe((result: AddPersonResult) => {...})

1.12 Making a PUT Request

  • Supply the request body as the second argument to the put() method.
updatePerson(person:Person) : Observable {
  return this.http.put("/app/person", person) 
}
  • If a PUT request returns data in the response body, you can make a more type-safe call.
updatePerson(person:Person) : Observable<UpdateResult> {
  return this.http.put<UpdateResult>("/app/person", 
    person) 
}
//The component
this.peopleService.updatePerson(...)
  .subscribe((result: UpdateResult) => {...})

1.13 Making a DELETE Request

  • A DELETE request does not take any body

deletePerson(id:number) : Observable { return this.http.delete(`/app/person/${id}`) }

  • If a DELETE request returns data in the response body, you can make a more type safe call.
deletePerson(id:number) : Observable<DeleteStatus> {
  return this.http.delete<DeleteStatus>(`/app/person/${id}`) 
}
//The component
this.peopleService.deletePerson(12)
  .subscribe((result: DeleteStatus) => {...})

1.14 Summary

In this tutorial, we covered:

  • What is the Angular HTTP Client
  • Importing HttpClientModule
  • Making Get/ Post Calls
  • Working with Observables

Follow Us

Blog Categories