Skip to main content

Angular - Http vs HttpClient

3 min read

Older Article

This article was published 8 years ago. Some information may be outdated or no longer applicable.

Angular 4.3 shipped a new Http service called HttpClient. It’s an upgrade over the old Http service with better functionality bolted on. Here’s what changed.

Angular > 4.3.x

If the Angular version is greater than 4.3, you can use the new HttpClient.

The import statement has been moved to a different package, so the old Http client still works. Non-breaking change. To pull in the HttpClient:

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

You’ll also need to import the HttpClientModule into your application:

// additional imports
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, HttpClientModule],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

JSON data returned by default

The new HttpClient formats the response as JSON by default. No more response.json():

constructor(private http: HttpClient) {
  this.http.get('http://my.api/data')
      .subscribe(response => console.log(response));
}

In older versions (< 4.3.x) you had to import the RxJS map method and parse the response manually:

// more code
import 'rxjs/add/operator/map';
// more code
constructor(private http: HttpClient) {
  this.http.get('http://my.api/data')
      .map((response: any) => response.json())
      .subscribe(response => console.log(response));
}

That step is gone. If you try it anyway, you’ll get TypeError: response.json is not a function.

Interceptors and middlewares

Interceptors let you intercept or mutate HTTP requests and responses. An interceptor is a TypeScript class (an injectable service) that implements HttpInterceptor:

import { Injectable } from '@angular/core';
import {
  HttpInterceptor,
  HttpHandler,
  HttpRequest,
  HttpEvent,
  HttpResponse,
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class MyInterceptor implements HttpInterceptor {
  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    request = request.clone({
      setHeaders: {
        'X-Custom-Header': 'Agent-007',
      },
    });
    return next.handle(request);
  }
}

The code above intercepts all requests and bolts on a new header (X-Custom-Header).

Both the request and response objects are immutable in the new HttpClient. If you want to modify them, you first need to create a copy (as shown above).

Progress events

The new HttpClient lets you capture progress events for uploads and downloads. To access them, you need to construct the HttpRequest manually:

// more code
import { HttpClient, HttpRequest, HttpEvent, HttpEventType } from '@angular/common/http';
// more code
constructor(private http: HttpClient) {
  const request = new HttpRequest('GET', 'http://my.api/data',
                                  {}, { reportProgress: true });
  this.http.request(request)
    .subscribe((event: HttpEvent<any>) => {
      switch (event.type) {
        case HttpEventType.Sent:
          console.log('Request started');
          break;
        case HttpEventType.ResponseHeader:
          console.log('Headers received ->', event.headers);
          break;
        case HttpEventType.DownloadProgress:
          const loaded = Math.round(event.loaded / 1024);
          console.log(`Downloading ${ loaded } kb downloaded`);
          break;
        case HttpEventType.Response:
          console.log('Finished -> ', event.body);
      }
    });
}

That’s the new HttpClient. Go use it.