23

I have an angular application with an HttpInterceptor that catch the http errors to show some dialog, common to all my application.

I would like to disable the interceptor for some specific calls but I prefer to disable the default behaviour where i call the http, instead of write an exception into the interceptor. Anyone have found this problem?

I can be more specific with an example, if needed.

Regards

Davide

Davide C
  • 830
  • 2
  • 11
  • 21
  • 2
    https://stackoverflow.com/questions/55522320/angular-interceptor-exclude-specific-urls/55522787#55522787 – Eliseo Feb 27 '20 at 07:37

3 Answers3

39

With Angular 12, it's possible now to include some metadata (with HttpContext) in your call that can be used within the interceptor to make decisions (or anything you want really).

Example

Your interceptor:

export const BYPASS_LOG = new HttpContextToken(() => false);

export class MyLogInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.context.get(BYPASS_LOG) === true)
      return next.handle(req);

    console.log(`req to ${req.url}`);

    return next.handle(req);
  }
}

Your service:

httpClient.get('https://example.com/', { context: new HttpContext().set(BYPASS_LOG, true) });

You can checkout angular docs for more information:

fasfsfgs
  • 956
  • 10
  • 16
26

You can use HttpBackend to do this.

Description: When injected, HttpBackend dispatches requests directly to the backend, without going through the interceptor chain.

Using: You can use same like HttpClientby import it from @angular/common/http

Example:

import { HttpClient, HttpBackend } from '@angular/common/http';

...

@Injectable({
  providedIn: 'root'
})
export class HttpHelperService {

  private httpClient: HttpClient;

  constructor( httpBackend: HttpBackend) { 
     this.httpClient = new HttpClient(httpBackend);
  }

  // use like normal with HttpClient. However, should name it carefully to separate which http request go throught interceptor and which is not
  put(path: string, body: Object = {}): Observable<any> {
    return this.httpClient.put(
      `${this.URL}${path}`,
      JSON.stringify(body)
    ).pipe(catchError(this.formatErrors));
  }

....

ref: https://angular.io/api/common/http/HttpBackend

Hoang Subin
  • 6,610
  • 6
  • 37
  • 56
  • For Angular version below 12, this is useful, but in my case by using HttpBackend, I was getting CORS error. So i followed the approach of setting headers and then putting a condition in intercepter, as explained in this answer https://stackoverflow.com/a/55522787/14069524 – Ch Asjad Mahmood Jun 28 '22 at 06:18
  • this isn't what user has asked, please update answer to help inquiry. – chris_r Feb 03 '23 at 06:55
1

You can also use a small service class to do this. The service just needs to toggle a flag to indicate whether the interceptor should run, and the interceptor class can check the flag before running.

@Injectable()
export class InterceptorOverrideService {

disableInterceptor = false;

constructor() { }

disable() {
   this.disableInterceptor = true;        
}

enable() {
  this.disableInterceptor = false;
}
}

And the Interceptor class:

export class MyInterceptor implements HttpInterceptor {

private count = 0;

constructor(private overrideService: InterceptorOverrideService) { }

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const methods = ['POST', 'PUT', 'PATCH', 'DELETE'];
    if (methods.indexOf(req.method) === -1 || this.overrideService.disableInterceptor) {
        return next.handle(req);
    }

    //Your Code here

    return next.handle(req).pipe(finalize(() => { //finalize is called for either success or error responses            
    }));
}
}
michael_hook
  • 1,936
  • 14
  • 10