The new HttpClient in Angular 4

Angular 4.3 was released with the addition of a new service to make HTTP requests: HttpClient.

The old Http service is still available and the main goal of HttpClient is to provide a simpler API out of the box.

Let’s see how the two compare for a simple HTTP GET request. First the new HttpClient:


constructor(private http: HttpClient) {
this.http.get("http://localhost:8080/personList")
.subscribe(res => this.persons = res );

And here is the same request made with the Http service:


constructor(private http: Http) {
this.http.get("http://localhost:8080/personList")
.map(res => res.json())
.subscribe(res => this.persons = res );
}

The only difference is that we don’t have to map the response to get our JSON data. HttpClient was written for JSON and as a result extracts our data for us.

Basically, Http.get() returns an Observable, where the Response is an HTTP response with HTTP headers, status code, and our data.

HttpClient.get() directly returns an Observable<Object> by default. It is just our data without the HTTP protocol information.

This is where HttpClient gets more interesting, as we can also define the type of the object we expect from the server using generics:


persons : Person[];

constructor(private http: HttpClient) {
// Now we expect the data to be an array of Person objects
this.http.get<Person[]>("http://localhost:8080/personList")
.subscribe(res => this.persons = res );
}

We can achieve the same strong typing with Http in a much more verbose way, which definitely highlights the benefits of using the new HttpClient:


persons : Person[];

constructor(private http: Http) {
let obs : Observable<Response> = http.get("....");
let obs2 : Observable<Person[]> = obs.map(res => res.json());
obs2.subscribe(res => this.persons = res);
}

What if I want to see the HTTP response?

Not a problem, just ask for it:


constructor(private http: HttpClient) {
this.http.get<Person[]>("....", {observe: 'response'}))
// Now res is of type HttpResponse.
// We can access our data through the body property.
.subscribe(res => this.persons = res.data );
}

What if I want to know when a HTTP error happens?

Just like with Http, you can register a handler for that. The error passed to the handler function will be of type HttpErrorResponse and has all of the information one would expect to find there:


constructor(private http: HttpClient) {
this.http.get<Person[]>("http://localhost:8080/personList"))
.subscribe(res => this.persons = res.data,
error => console.log(`Server error: ${err.status} - Details: ${err.error}`)
);
}

Now you know about the main differences between Http and HttpClient from a usage standpoint.

But HttpClient has a lot more to offer:

  • We can register interceptors for HTTP requests and responses (à la Angular JS)
  • There is also a HttpClientTestingModule to easily mock our HTTP requests for testing purposes

Interceptors are a major feature and I will talk about them in more details with a specific tutorial in the near future.

Some use cases of interceptors include, and are not limited to:

  • Adding HTTP headers on the fly for every single HTTP request (think authentication token for instance)
  • Implementing your own caching mechanism
  • Watching the progress of your request to display an accurate progress bar

The new HttpClient comes with Angular 4.3 in a new module: HttpClientModule, which is found in the @angular/common/http package.

Don’t hesitate to give it a try!

Alain Chautard

Alain started working with Angular JS in 2011, back when version 1.0 wasn’t even released yet.

He is the organizer of the Sacramento Angular Meetup group, co-organizer of the Google Developer Group chapter in Sacramento, California, and published author of the Packt video course “Migrating to Angular 2“.