Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Http Interceptor not working in child module

So I created an angular2 module to handle HTTP Intercepting, using a basic interceptor like so:

@Injectable()
export class RequestInterceptor implements HttpInterceptor {
  constructor(private injector: Injector) {}

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const authService = this.injector.get(AuthService);
    if(authService.isAuthenticated()){
      const authReq = request.clone({
        setHeaders: {
          Authorization: `Bearer ${authService.getAccessToken()}`
        }
      });
      let handle = next.handle(authReq).do(event => {
        if(event instanceof HttpResponse){
          if(event.headers.has('Authorization')){
            authService.updateToken(event.headers.get('Authorization').split(' ')[1]);
          }
        }
      });
      return handle;
    }else{
      return next.handle(request);
    }
  }
}

Which will add an authorization header to http requests and update its own header when a new one is sent from the server. Its imported and provided normally like so:

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

So the auth angular2 module is compiled and imported into my app.module.t, it works great. Until I tried to use it from a child module. The top answer from here: Inherit imports from parent module to child module in Angular2 claims that angular2 wont let you make things available globally to the whole app. Is this correct?

I got it working from the child module by just importing the RequestInterceptor, and setting it up in the providers for the module, but I'd rather not have to do so to make it less cumbersome to use.

like image 513
Ronin Avatar asked Feb 12 '18 22:02

Ronin


2 Answers

Not the best answer - but check out this bug: https://github.com/angular/angular/issues/20575

Specifically the comment that reads:

You should import the HttpClientModule only once, see docs

I imagine that you are re-importing the HttpClientModule somewhere in your Module tree - likely in another child module. If you just declare it once, in the AppModule (or one if it's imports) then it should start working everywhere. That was my experience anyhow.

That kind of stinks - and feels ripe for causing bugs down the road when another dev imports it in a ChildModule later, and doesn't realize the intercept logic is no longer working. But that seems to be the way it is.

like image 91
MattW Avatar answered Oct 23 '22 10:10

MattW


I came across with a similar problem. I got a custom HTTP interceptor for purpose of sending JWT to API and weirdly while some of my components working properly, some of them just rejected by server with 401. After some trial & errors, I read @MattW's answer and realized that there are multiple HttpClientModules imported in my application. I cleared them all and imported HttpClientModule only in the AppModule (root). After that, all is fixed.

like image 4
FShieldheart Avatar answered Oct 23 '22 10:10

FShieldheart