What is httpinterceptor equivalent in angular2?

HttpAngular

Http Problem Overview


In angularjs, we have http interceptor

$httpProvider.interceptors.push('myHttpInterceptor');

with which we can hook into all http calls, and show or hide loading bars, do logging, etc..

What is the equivalent in angular2?

Http Solutions


Solution 1 - Http

As @Günter pointed it out, there is no way to register interceptors. You need to extend the Http class and put your interception processing around HTTP calls

First you could create a class that extends the Http:

@Injectable()
export class CustomHttp extends Http {
  constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) {
    super(backend, defaultOptions);
  }

  request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
    console.log('request...');
    return super.request(url, options).catch(res => {
      // do something
    });        
  }

  get(url: string, options?: RequestOptionsArgs): Observable<Response> {
    console.log('get...');
    return super.get(url, options).catch(res => {
      // do something
    });
  }
}

and register it as described below:

bootstrap(AppComponent, [HTTP_PROVIDERS,
    new Provider(Http, {
      useFactory: (backend: XHRBackend, defaultOptions: RequestOptions) => new CustomHttp(backend, defaultOptions),
      deps: [XHRBackend, RequestOptions]
  })
]);

The request and requestError kinds could be added before calling the target methods.

For the response one, you need to plug some asynchronous processing into the existing processing chain. This depends on your need but you can use operators (like flatMap) of Observable.

Finally for the responseError one, you need to call the catch operator on the target call. This way you will be notified when an error occurs in the response.

This links could help you:

Solution 2 - Http

update

The new HttpClient module introduced in Angular 4.3.0 supports interceptors https://github.com/angular/angular/compare/4.3.0-rc.0...4.3.0

> feat(common): new HttpClient API HttpClient is an evolution of the > existing Angular HTTP API, which exists alongside of it in a separate > package, @angular/common/http. This structure ensures that existing > codebases can slowly migrate to the new API. > > The new API improves significantly on the ergonomics and features of > the legacy API. A partial list of new features includes: > > * Typed, synchronous response body access, including support for JSON body types > * JSON is an assumed default and no longer needs to be explicitly parsed > * Interceptors allow middleware logic to be inserted into the pipeline > * Immutable request/response objects > * Progress events for both request upload and response download > * Post-request verification & flush based testing framework

original

Angular2 doesn't have (yet) interceptors. You can instead extend Http, XHRBackend, BaseRequestOptions or any of the other involved classes (at least in TypeScript and Dart (don't know about plain JS).

See also

Solution 3 - Http

There's an implementation for a Http @angular/core-like service in this repository: https://github.com/voliva/angular2-interceptors

You just declare the provider for that service on bootstrap, adding any interceptors you need, and it will be available for all the components.

import { provideInterceptorService } from 'ng2-interceptors';

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...,
    HttpModule
  ],
  providers: [
    MyHttpInterceptor,
    provideInterceptorService([
      MyHttpInterceptor,
      /* Add other interceptors here, like "new ServerURLInterceptor()" or
         just "ServerURLInterceptor" if it has a provider */
    ])
  ],
  bootstrap: [AppComponent]
})

Solution 4 - Http

DEPRICATED SINCE Angular 4.3 (HttpInterCeptors are Back in 4.3)

You can create your own custom HTTP Class and use rxjs Subject Service to reuse your custom Http Class and implement your behaviors in a custom class.

Implementation of your Custom Http Class with "HttpSubjectService" which contains some rxjs Subjects.

import { Injectable } from '@angular/core';
import { Http, ConnectionBackend, Request, RequestOptions, RequestOptionsArgs, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';


import { HttpSubjectService } from './httpSubject.service';


@Injectable()
export class CustomHttp extends Http {
   constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private httpSubjectService: HttpSubjectService) {
       super(backend, defaultOptions);

       //Prevent Ajax Request Caching for Internet Explorer
       defaultOptions.headers.append("Cache-control", "no-cache");
       defaultOptions.headers.append("Cache-control", "no-store");
       defaultOptions.headers.append("Pragma", "no-cache");
       defaultOptions.headers.append("Expires", "0");
   }

   request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
       //request Start;
       this.httpSubjectService.addSpinner();
       return super.request(url, options).map(res => {
           //Successful Response;
           this.httpSubjectService.addNotification(res.json());
           return res;
       })
           .catch((err) => {
               //Error Response.
               this.httpSubjectService.removeSpinner();
               this.httpSubjectService.removeOverlay();

               if (err.status === 400 || err.status === 422) {
                   this.httpSubjectService.addHttp403(err);
                   return Observable.throw(err);
               } else if (err.status === 500) {
                   this.httpSubjectService.addHttp500(err);
                   return Observable.throw(err);
               } else {
                   return Observable.empty();
               }
           })
           .finally(() => {
               //After the request;
               this.httpSubjectService.removeSpinner();
           });
   }
}

Custom module to register your CustomHttp class - here you overwrite the default Http implementation from Angular with your own CustomHttp Implementation.

import { NgModule, ValueProvider } from '@angular/core';
import { HttpModule, Http, XHRBackend, RequestOptions } from '@angular/http';

//Custom Http
import { HttpSubjectService } from './httpSubject.service';
import { CustomHttp } from './customHttp';

@NgModule({
    imports: [ ],
    providers: [
        HttpSubjectService,
        {
           provide: Http, useFactory: (backend: XHRBackend, defaultOptions: RequestOptions, httpSubjectService: HttpSubjectService) => {
                return new CustomHttp(backend, defaultOptions, httpSubjectService);
            },
            deps: [XHRBackend, RequestOptions, HttpSubjectService]
        }
    ]
})
export class CustomHttpCoreModule {

    constructor() { }
}

now we need the HttpSubjectService Implementation where we can SubScribe to our rxjs Subjects when they get called with the "next" statement.

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class HttpSubjectService {
    //https://github.com/ReactiveX/rxjs/blob/master/doc/subject.md
    //In our app.component.ts class we will subscribe to this Subjects
    public notificationSubject = new Subject();
    public http403Subject = new Subject();
    public http500Subject = new Subject();
    public overlaySubject = new Subject();
    public spinnerSubject = new Subject();

    constructor() { }

    //some Example methods we call in our CustomHttp Class
    public addNotification(resultJson: any): void {
        this.notificationSubject.next(resultJson);
    }

    public addHttp403(result: any): void {
        this.http403Subject.next(result);
    }

    public addHttp500(result: any): void {
        this.http500Subject.next(result);
    }

    public removeOverlay(): void {
        this.overlaySubject.next(0);
    }

    public addSpinner(): void {
        this.spinnerSubject.next(1);
    }

    public removeSpinner(): void {
        this.spinnerSubject.next(-1);
    }
}

to call your custom Implementations we need to Subscribe to the Subjects in the e.g. "app.component.ts".

import { Component } from '@angular/core';
import { HttpSubjectService } from "../HttpInterception/httpSubject.service";
import { Homeservice } from "../HttpServices/home.service";

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
})
export class AppComponent {
    private locals: AppLocalsModel = new AppLocalsModel();

    constructor(private httpSubjectService : HttpSubjectService, private homeService : Homeservice) {}

    ngOnInit(): void {
        this.notifications();
        this.httpRedirects();
        this.spinner();
        this.overlay();
    }

    public loadServiceData(): void {
        this.homeService.getCurrentUsername()
            .subscribe(result => {
                this.locals.username = result;
            });
    }

    private overlay(): void {
        this.httpSubjectService.overlaySubject.subscribe({
            next: () => {
              console.log("Call Overlay Service");
            }
        });
    }

    private spinner(): void {
        this.httpSubjectService.spinnerSubject.subscribe({
            next: (value: number) => {
              console.log("Call Spinner Service");
            }
        });
    }

    private notifications(): void {
        this.httpSubjectService.notificationSubject.subscribe({
            next: (json: any) => {
                console.log("Call Notification Service");
            }
        });
    }

    private httpRedirects(): void {
        this.httpSubjectService.http500Subject.subscribe({
            next: (error: any) => {
                console.log("Navigate to Error Page");
            }
        });

        this.httpSubjectService.http403Subject.subscribe({
            next: (error: any) => {
                console.log("Navigate to Not Authorized Page");
            }
        });
    }
}


class AppLocalsModel {
    public username : string = "noch nicht abgefragt";
}

SINCE ANGULAR 4.3 you can Use InterCeptors

In Angular 4.3 you have native Interceptors where you can implement your own stuff like a redirect for server error 500

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

@Injectable()
export class SxpHttp500Interceptor implements HttpInterceptor {

  constructor(public router: Router) { }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
      return next.handle(req).do(evt => { }).catch(err => {
          if (err["status"]) {
              if (err.status === 500) {
                  this.router.navigate(['/serverError', { fehler: JSON.stringify(err) }]);
              }
          }
          return Observable.throw(err);
      });
  }
}

you need to Register this in your core module in the providers Array

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { Router } from '@angular/router';
import { SxpHttp500Interceptor } from "./sxpHttp500.interceptor";
 ....

providers: [
    {
        provide: HTTP_INTERCEPTORS, useFactory: (router: Router) => { return new SxpHttp500Interceptor(router) },
        multi: true,
        deps: [Router]
    }
]

Solution 5 - Http

With the Angular 4.3.1 release, there's now an interface called HttpInterceptor.

Here's the link to the docs: https://angular.io/api/common/http/HttpInterceptor

Here's an implementation sample.


This would be the interceptor class implementation.

Is basically written as any other service:

@Injectable()
export class ExceptionsInterceptor implements HttpInterceptor {
    constructor(
        private logger: Logger,
        private exceptionsService: ExceptionsService,
        private notificationsService: NotificationsService
    ) { }
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        return next.handle(request)
            .do((event) => {
                // Do nothing here, manage only errors
            }, (err: HttpErrorResponse) => {
                if (!this.exceptionsService.excludeCodes.includes(err.status)) {
                    if (!(err.status === 400 && err.error['_validations'])) {
                        this.logger.error(err);
                        if (!this.notificationsService.hasNotificationData(err.status)) {
                            this.notificationsService.addNotification({ text: err.message, type: MessageColorType.error, data: err.status, uid: UniqueIdUtility.generateId() });
                        }
                    }
                }
            });
    }
}

Then since you'll treat this like a normal service, you have to add this line inside your app module's providers:

{ provide: HTTP_INTERCEPTORS, useClass: ExceptionsInterceptor, multi: true }

Hope it can help.

Solution 6 - Http

Angular 4.3 now supports Http interceptor out-of-the-box. Check it out how to use them: https://ryanchenkie.com/angular-authentication-using-the-http-client-and-http-interceptors

Solution 7 - Http

I have released interceptor with following node module. We was create this module for our internal purpose finally we released in npm package manager npm install angular2-resource-and-ajax-interceptor https://www.npmjs.com/package/angular2-resource-and-ajax-interceptor

Solution 8 - Http

As @squadwuschel pointed out, work is underway to get this functionality into @angular/http. This will be in the form of a new HttpClient API.

See https://github.com/angular/angular/pull/17143 for more details and current status.

Solution 9 - Http

Try Covalent from Teradata, they provides lots of extensions for Angular and Angular Material.

Check HTTP part, it provides the missing http interceptor in Angular and RESTService(similar to restangular).

I have implemented JWT token authentication via Covalent HTTP in my sample, Please check here.

https://github.com/hantsy/angular2-material-sample/blob/master/src/app/core/auth-http-interceptor.ts

Read my development notes for it, Handle token based Authentication via IHttpInterceptor.

Solution 10 - Http

Angular2 donot support httpinterceptor like angular1

Here is awesome example of use of httpinterceptor in angular2.

https://github.com/NgSculptor/ng2HttpInterceptor

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionVikram Babu NagineniView Question on Stackoverflow
Solution 1 - HttpThierry TemplierView Answer on Stackoverflow
Solution 2 - HttpGünter ZöchbauerView Answer on Stackoverflow
Solution 3 - Httpolivarra1View Answer on Stackoverflow
Solution 4 - HttpsquadwuschelView Answer on Stackoverflow
Solution 5 - HttpCaiusView Answer on Stackoverflow
Solution 6 - HttpMartino BordinView Answer on Stackoverflow
Solution 7 - HttpRajanView Answer on Stackoverflow
Solution 8 - HttprdukeshierView Answer on Stackoverflow
Solution 9 - HttpHantsyView Answer on Stackoverflow
Solution 10 - HttpEr. Bahuguna GoyalView Answer on Stackoverflow