The new Angular HttpClient API
The HttpClient API was introduced in the version 4.3.0. It is an evolution of the existing HTTP API and has it's own package @angular/common/http.

Series
This post is part of the HttpClient API series:
- The new Angular
HttpClient
API - Testing with the Angular
HttpClientTesting
API
The HttpClient
API was introduced in the version 4.3.0
. It is an evolution of the existing HTTP
API and has it's own package @angular/common/http
. This article gives you an overview of the new main features the new client introduces. For the in-depth look under that hood of the HttpClient
check out Insider’s guide into interceptors and HttpClient mechanics in Angular.
One of the most notable changes is that now the response object is a JSON by default, so there's no need to parse it anymore. We can do:
// HttpClient
this.http.get('https://api.github.com/users')
.subscribe(data => console.log(data));
Rather than:
// Http
this.users = this.http.get('https://api.github.com/users')
.map(response => response.json())
.subscribe(data => console.log(data));
However if you're still interested in the whole Response
object you can observe
for it:
// HttpClient
this.http.get('…', { observe: 'response' });
Query parameters
One thing that might not be as intuitive is the way that it handles query parameters. You can't just really pass a Plain Old JavaScript Object (POJO) over and expect it to be assigned as a query parameter of the request like you would with any other option that can be passed to the options
object of the GET
call.
import { HttpParams } from '@angular/common/http';
const params = new HttpParams().set('q', 'cironunes');
this.http.get('...', { params });
This is a bit verbose. Luckily there's already a pull request in place to enable the usage of object maps for parameters and headers of GET
requests.
Type checking responses
Thanks to TypeScript Generics you type HTTP method you’re calling and the response will get be of that same type:
interface LoginResponse {
accessToken: string;
accessExpiration: number;
}
this.http.post<LoginResponse>('api/login', {
login: 'foo',
password: 'bar'
}).subscribe(data => {
console.log(data.accessToken, data.accessExpiration);
});
Requesting non-JSON data
Although it’s the most common, sometimes you’ll deal with different sorts of data. This is supported via the responseType
property.
this.http.get('...', { responseType: 'text' });
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text'
In this case you don’t need to type the response as the reponseType
already do the trick.
Interceptors
The most exciting thing of the HttpClient
is the introduction of Interceptors which allow middleware logic to be inserted in the pipeline. Let's take a quick look at how it works.
First of all let's create an interceptor. An Interceptor needs to implement the HttpInterceptor
interface which is about implementing the intercept
method.
interface HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>;
}
The intercept method receives an HttpRequest
and must return an stream of HttpEvent
of type HttpResponse
. As the Request
and Response
objects are immutable — which makes it easier to predict and test, we use the clone
method to mutate the Response
object.
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpEventType } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<HttpEventType.Response>> {
const authReq = req.clone({
setHeaders: { Authorization: `Bearer authtest` }
});
return next.handle(authReq);
}
}
You register them like that:
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
@NgModule({
imports: [],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true }
]
})
export class AppModule {}
If you want to register many interceptors you can just put more items in the providers array.
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: First, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: Second, multi: true }
]
Listening for progress
Another very cool feature is that you can subscribe for events like the upload or download progress via reportProgress
option. In a file upload example it would be like that:
const req = new HttpRequest('POST', 'upload/file', file, {
reportProgress: true
});
this.http.request(req)
.subscribe(event => {
if (event.type === HttpEventType.UploadProgress) {
console.log(event.total, event.loaded);
}
});
Wrapping up
The HttpClient
API is awesome. Besides favouring the most common use cases, it enforces once again the usage of Observables and Immutable objects whenever it makes sense. That makes using it easier and easy to test code that uses it.
What’s next?
I’ll cover testing with the HttpClientTestingModule
in the next post. Stay tuned.