Reputation: 1429
I'm in the proces of adding an interceptor to my angular 6 project. To make calls to my API, I need to add a bearer token to all calls. Unfortunately the interceptor does not seem to be called. My code:
import { Injectable } from "@angular/core";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "@angular/common/http";
import { Observable } from "rxjs";
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>,
next: HttpHandler): Observable<HttpEvent<any>> {
//Retrieve accesstoken from local storage
const accessToken = localStorage.getItem("access_token");
//Check if accesToken exists, else send request without bearer token
if (accessToken) {
const cloned = req.clone({
headers: req.headers.set("Authorization",
"Bearer " + accessToken)
});
console.log('Token added to HTTP request');
return next.handle(cloned);
}
else {
//No token; proceed request without bearer token
console.log('No token added to HTTP request');
return next.handle(req);
}
}
}
Does anyone know what could be causing this issue? Thanks in advance.
Upvotes: 63
Views: 80768
Reputation: 31
Follow this rule when you are dealing with the HttpClientModule and HttpInterceptors, keep import HttpClientModue and Http Interceptor Register in the same Module. if you don't, some interceptors will be missing.
In general, we always import HttpClientModule and HttpInterceptors into the app.module.ts. Don't import HttpClientModule from child Module. If you really have to import HttpClientModule, remember to register the HttpInterceptors again in the same module. one such case is from Lazy Load Module.
Maybe someone still say that my HttpClientModule and HttpInterceptors are from the same module, why my httpClient not working as expected. So here, we have the last rule. make sure the httpClient instance is constructed after HttpClientModule imported and HttpInterceptors imported.
Upvotes: 1
Reputation: 5686
I had the exact same behavior with my standalone component (interceptors not intercepting my http requests).
If you use standalone components instead of importing HttpClientModule in your Module, note that you have to add withInterceptorsFromDi()
in your provideHttpClient(...)
to make your interceptors work! Or use the new way of functional interceptors via withInterceptors
.
See this SO post for more details.
Upvotes: 10
Reputation: 1785
In my case interceptor wasn't getting involved for service calls because I had imported HttpClientModule
multiple times, for different modules.
Later I found that HttpClientModule
must be imported only once. Doc ref
Upvotes: 141
Reputation: 5686
In my case the HttpClient was not used to do the requests.
Instead fetch has been used directly and that is not intercepted by angular.
Changed fetch(...)
to http.get(...)
and it worked
Upvotes: 2
Reputation: 55
Check your module & sub-module files, If you have imported the interceptor in a sub-module, then move it to the root module and it should work.
Upvotes: 2
Reputation: 37
In my case, since I am working with modules, I had to import the child module (AuthModule) in app.module.ts. I was just missing that.
imports: [ HttpClientModule, AppRoutingModule, AuthModule ]
Upvotes: 0
Reputation: 7381
In my case i had a post method like this:
this.http.post<any>(this.authUrl, JSON.stringify({username: username, password: password})).pipe(
map((response: any) => {
let token: any = response.token;
if (token) {
localStorage.setItem('currentUser', 'value' }));
return response;
} else {
return null;
}
}),
catchError((error:any) => {return observableThrowError(error.json().error || 'Server error')})
);
Because the map
method could return null
the interceptor stopped intercepting the requests made with this post method call. Don't ask me why this is so, but as soon as i replace null
with say response
everything started working again.
Upvotes: 3
Reputation: 1
Please ensure that dependencies for the interceptor are also provided in the module. ProvidedIn:'root' for the interceptor dependency services did not work for me.
Upvotes: 0
Reputation: 1
In my case I accidentally had my service proivded providers : [ ApplicationService ]
in my component when it wasn't supposed to be as I had it defined using providedIn: 'root'
Upvotes: 0
Reputation: 713
In my case, I had to import both HTTP_INTERCEPTORS, HttpClientModule
in same module.
Upvotes: 3
Reputation: 1710
You use the right way to intercept.
For people who use interceptor, you need to do 2 modifications :
Interceptor in service
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpHandler, HttpRequest, HttpEvent, HttpResponse }
from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
@Injectable()
export class MyInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(req).do(evt => {
if (evt instanceof HttpResponse) {
console.log('---> status:', evt.status);
console.log('---> filter:', req.params.get('filter'));
}
});
}
}
Provide HTTP_INTERCEPTOR
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
(...)
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: MyInterceptor, multi: true }
],
Read this article for more details. It's pretty good
Upvotes: 49
Reputation: 99
If you have a providers array for a module then you have to define the HTTP_INTERCEPTORS too for that module then only it will intercept the requests under that module.
e.g:
providers: [
// singleton services
PasswordVerifyService,
{ provide: HTTP_INTERCEPTORS, useClass: AppInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptorService, multi: true }
]
Upvotes: 9