34

I am writing interceptors such that I don't have to handle the headers in every service calling my web api. The problem with this is that 99% of my calls require 1 specific set of headers, but the other 1% only require 1 of the headers and will not work with the others present. With this being known my idea is to make 2 interceptors, the first will add the 1 header that they all use and the second will add the rest of the headers, with the second excluding the 1%.

The following is how I am going about excluding the 1%, which works, but I want to see if there is a better way of going about this:

intercept(request: HttpRequest<any>, next:HttpHandler: Observable<HttpEvent<any>> {
  let position = request.url.indexOf('api/');
  if (position > 0){
    let destination: string = request.url.substr(position + 4);
    let matchFound: boolean = false;

    for (let address of this.addressesToUse){
      if (new RegExp(address).test(destination)){
        matchFound = true;
        break;
      }
    }

    if (!matchFound){
      ...DO WORK to add the headers
    }
  }
2

7 Answers 7

68

Update from Angular 12, use "context", see this SO

I suggest that, in spite of check the request, you can use the header to add a "skip" property, if the header has the skip property, simple return the reqs

export class CustomInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        if (req.headers.get("skip"))
           return next.handle(req);
      
        ....
    }
}

And you make all the calls you need "skip" the interceptor like

this.http.get(url, {headers:{skip:"true"}});
Sign up to request clarification or add additional context in comments.

2 Comments

Sorry for my stupid. I can't find the options {headers:{skip:"true"} online.
You can add any header you want. I like the name "skip", but you can choose what ever (e.g. in some platform for e-comerce you add some like API-KEY)
28

after checking for req.headers.get("skip") as Eliseo suggested, I'd recommend removing this header from request since it's Angular-related only and it should not be transmitted to the API (actually it can cause issues)

const skipIntercept = request.headers.has('skip');

if (skipIntercept) {
    request = request.clone({
        headers: request.headers.delete('skip')
    });
}

Comments

19

What I wound up doing is having an array of urls (in Regex Format) that I did not want to be used in the interceptor like so:

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class AddCustomHeadersInterceptor implements HttpInterceptor {
  urlsToNotUse: Array<string>;

  constructor(
  ) {

    this.urlsToNotUse= [
      'myController1/myAction1/.+',
      'myController1/myAction2/.+',
      'myController1/myAction3'
    ];
  }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (this.isValidRequestForInterceptor(request.url)) {
      let modifiedRequest = request.clone({
        setHeaders: {
          //DO WORK HERE
        }
      });

      return next.handle(modifiedRequest);
    }
    return next.handle(request);
  }

  private isValidRequestForInterceptor(requestUrl: string): boolean {
    let positionIndicator: string = 'api/';
    let position = requestUrl.indexOf(positionIndicator);
    if (position > 0) {
      let destination: string = requestUrl.substr(position + positionIndicator.length);
      for (let address of this.urlsToNotUse) {
        if (new RegExp(address).test(destination)) {
          return false;
        }
      }
    }
    return true;
  }
}

Comments

18

When created by default, HttpClient will use interceptor. If you want to avoid this, you can create another instance of HttpClient using constructor.

@Injectable()
class Service {
  private customHttpClient: HttpClient;

  constructor(backend: HttpBackend) {
    this.customHttpClient = new HttpClient(backend);
  }
}

The customHttpClient instance will not use the interceptor.

1 Comment

I think this is the best straight forward way to do it
1

You can try to extent HttpClient instead of using Interceptors.

In an Interceptor World every request is stopped - massaged (headers are added) - before executed.

In a HttpClient World it would be taken care at the time of Client object instantiation.

If you deem it necessary, you can consider having different variants per se, HttpClient99Percent variant, HttpClientOnePercent variant etc.

Below link can give you a head start:

https://medium.com/@admin_87321/extending-angular-httpclient-6b33a7a1a4d0

Comments

0

update of Андрей Керничный's answer

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

@Injectable({
  providedIn: 'root'
})
export class CartService {
  private customHttpClient: HttpClient;

  constructor(private http: HttpClient, backend: HttpBackend) { 
    this.customHttpClient = new HttpClient(backend);
  }

  getZohoItems() {
    // call zoho url
    return this.customHttpClient.get('http://zoho.com/api/orders/');
  }

  getItems() {
    // call localhost:8000 url
    return this.http.get('/api/orders/');
  }
}

Comments

0
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.indexOf('Url that you want to hide') === -1) {
  this.spinner.show();
  return next.handle(req).pipe(
    finalize(() => this.spinner.hide())
  );
}
if (req.url.indexOf('Url that you want to hide') !== -1) {
  this.spinner.hide();
}
return next.handle(req);

}

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.