Recently I have been using Interceptors with Angular HttpClient.
I add headers corresponding to some HTTP GET methods and for some I do not need those headers.
How can I tell my interceptor to conditionally add interceptors to only those methods? I can even split up services like one service for headers and one without headers or one for different headers and one for different.
NgModule providers
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true,
},{
provide: HTTP_INTERCEPTORS,
useClass: AngularInterceptor,
multi: true,
}
MyInterceptors
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authReq = req.clone({headers: req.headers.set('X-Auth-Token', "-------------------------")});
return next.handle(authReq);
}
}
@Injectable()
export class AngularInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).do(event => {}, err => {
if(err instanceof HttpErrorResponse){
console.log("Error Caught By Interceptor");
//Observable.throw(err);
}
});
}
}
After providing HTTP_INTERCEPTORS we need to inform the class we are going to implement our interceptor into by using useClass. Setting multi to true, makes sure that you can have multiple interceptors in your project.
So now to bypass the interceptor we can use HttpBackend. For more details about it, please refer to this. When injected, HttpBackend dispatches requests directly to the backend, without going through the interceptor chain. So as per the definition, we can surely use it for our current use case.
The interceptor needs to be added to the HTTP_INTERCEPTORS array. This is done by converting the existing HTTP_INTERCEPTORS array using the new class we created. Add this to the ProvidersArray for our application's modules. Any interceptor we want to create needs to implement the HttpInterceptor interface.
I know it is too late however, we still do not have any solution from Angular. An easy workaround at the moment is to create a BehaviorSubject and activate the Interceptor according to the value it. With this, you are able to handle specifics HTTP requests the must use your Interceptors:
yourService.service.ts
public interceptorTwo = new BehaviorSubject<boolean>(null);
someHttpmethod() {
this.interceptorTwo.next(true);
// Add your CODE http
this.myHttp.post<any>('someUrl', data).finally(() => this.interceptorTwo.next(null));
}
yourInterceptorTwo.service.ts
const setAuth = this.yourService.interceptorTwo.value;
if (!setAuth) {
return next.handle(req);
}
Note: I haven't tried this approach myself yet but have played with the idea because we are looking at a similar problem.
If we had very simple requirements, it would be trivial to add logic in a general purpose interceptor and just decide based on URL/Method which kind of interception to perform. However, our angular app needs to call a variety of 1st party micro-services and 3rd party APIs with different requirements for interceptors. This is effectively a superset of your requirements.
One idea to implement this is to extend HttpClient for each API/Service that we need to call and set up a custom injection token for the interceptor chain. You can see how angular registers the default HttpClient
here:
providers: [
HttpClient,
// HttpHandler is the backend + interceptors and is constructed
// using the interceptingHandler factory function.
{
provide: HttpHandler,
useFactory: interceptingHandler,
deps: [HttpBackend, [new Optional(), new Inject(HTTP_INTERCEPTORS)]],
},
The interceptingHandler
function is even exported as ɵinterceptingHandler
. I agree this looks a little weird, not sure why it has that export name.
Anyawy, to use a custom HttpClients you can probably:
export const MY_HTTP_INTERCEPTORS = new InjectionToken<HttpInterceptor[]>('MY_HTTP_INTERCEPTORS');
...
providers: [
MyHttpClient,
{
provide: MyHttpHandler,
useFactory: interceptingHandler,
deps: [HttpBackend, [new Optional(), new Inject(MY_HTTP_INTERCEPTORS)]],
},
And make sure that MyHttpClient
requires a MyHttpHandler
in its constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With