Mikey123
Mikey123

Reputation: 1429

Interceptor not intercepting http requests (Angular 6)

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

Answers (12)

xiangjianwu
xiangjianwu

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

andymel
andymel

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

Praveen Pandey
Praveen Pandey

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

andymel
andymel

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

Kashif Abdul Aleem
Kashif Abdul Aleem

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

Keliz Zorrilla
Keliz Zorrilla

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

Maurice
Maurice

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

Akhilesh Tiwari
Akhilesh Tiwari

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

ScottSpittle
ScottSpittle

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

M Faisal Hameed
M Faisal Hameed

Reputation: 713

In my case, I had to import both HTTP_INTERCEPTORS, HttpClientModule in same module.

Upvotes: 3

Pterrat
Pterrat

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

Ajit Das
Ajit Das

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

Related Questions