w3resource

HttpClient

The HttpClient in @angular/common/http offers a simplified client HTTP API for Angular applications that rests on the XMLHttpRequest interface exposed by browsers. Additional benefits of HttpClient include testability features, typed request and response objects, request and response interception, Observable APIs, and streamlined error handling.

Setup

Before you can use the HttpClient, you need to import the Angular HttpClientModule. Most apps do so in the root AppModule.

TypeScript Code:

import { NgModule }         from '@angular/core';
import { BrowserModule }    from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    BrowserModule,
    // import HttpClientModule after BrowserModule.
    HttpClientModule,
  ],
  declarations: [
    AppComponent,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen HttpClient_app.module.ts by w3resource (@w3resource) on CodePen.


Having imported HttpClientModule into the AppModule, you can inject the HttpClient into an application class as shown below:

TypeScript Code:

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

@Injectable()
export class ConfigService {
  constructor(private http: HttpClient) { }
}

Live Demo:

It is just a code snippet explaining a particular concept and may not have any output

See the Pen HttpClient_config.service.ts by w3resource (@w3resource) on CodePen.


Getting JSON data

Applications often request JSON data from the server. For example, the app might need a configuration file on the server, config.json, that specifies resource URLs.

{
  "heroesUrl": "api/heroes",
  "textfile": "assets/textfile.txt"
}

The ConfigService fetches this file with a get() method on HttpClient.

configUrl = 'assets/config.json';
getConfig() {
  return this.http.get(this.configUrl);
}

A component, such as ConfigComponent, injects the ConfigService and calls the getConfig service method.

showConfig() {
  this.configService.getConfig()
    .subscribe((data: Config) => this.config = {
        heroesUrl: data['heroesUrl'],
        textfile:  data['textfile']
    });
}

Because the service method returns an Observable of configuration data, the component subscribes to the method's return value. The subscription callback copies the data fields into the component's config object, which is data-bound in the component template for display.

Reading the full response

The response body doesn't return all the data you may need. Sometimes servers return special headers or status codes to indicate certain conditions that are important to the application workflow.

Tell HttpClient that you want the full response with the observe option:

getConfigResponse(): Observable<HttpResponse<Config>> {
  return this.http.get<Config>(
    this.configUrl, { observe: 'response' });
}

Now HttpClient.get() returns an Observable of typed HttpResponse rather than just the JSON data.

The component's showConfigResponse() method displays the response headers as well as the configuration.

Error handling

What happens if the request fails on the server, or if a poor network connection prevents it from even reaching the server? HttpClient will return an error object instead of a successful response.

You could handle in the component by adding a second callback to the.subscribe():

showConfig() {
  this.configService.getConfig()
    .subscribe(
      (data: Config) => this.config = { ...data }, // success path
      error => this.error = error // error path
    );
}

It's certainly a good idea to give the user some kind of feedback when data access fails. But displaying the raw error object returned by HttpClient is far from the best way to do it.

Getting error details

Detecting that an error occurred is one thing. Interpreting that error and composing a user-friendly response is a bit more involved. Two types of errors can occur. The server backend might reject the request, returning an HTTP response with a status code such as 404 or 500. These are error responses.

Or something could go wrong on the client-side such as a network error that prevents the request from completing successfully or an exception thrown in an RxJS operator. These errors produce JavaScript ErrorEvent objects.

The HttpClient captures both kinds of errors in its HttpErrorResponse and you can inspect that response to figure out what really happened.

Error inspection, interpretation, and resolution is something you want to do in the service, not in the component.

Making a POST request

Apps often POST data to a server. They POST when submitting a form. In the following example, the HeroesService posts when adding a hero to the database.

/** POST: add a new hero to the database */
addHero (hero: Hero): Observable<Hero> {
  return this.http.post<Hero>(this.heroesUrl, hero, httpOptions)
    .pipe(
      catchError(this.handleError('addHero', hero))
    );
}

The HttpClient.post() method is similar to get() in that it has a type parameter (you're expecting the server to return the new hero) and it takes a resource URL.

It takes two more parameters:

  • hero - the data to POST in the body of the request.
  • httpOptions - the method options which, in this case, specify required headers.

Previous: Navigate the component tree with DI
Next: Animation transitions and triggers



Share this Tutorial / Exercise on : Facebook and Twitter