Skip to content

Instantly share code, notes, and snippets.

@ricmello
Created November 24, 2019 17:06
Show Gist options
  • Save ricmello/849a205ef17c2754ba819908f6fd4efb to your computer and use it in GitHub Desktop.
Save ricmello/849a205ef17c2754ba819908f6fd4efb to your computer and use it in GitHub Desktop.
Http service that allows disable interceptors or pass misc data to Angular httpClient
import {
Inject,
Injectable,
InjectionToken,
Injector,
Optional
} from '@angular/core';
import {
HttpClient,
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { ApiPrefixInterceptor } from '../interceptors/api-prefix.interceptor';
import { AuthInterceptor } from '../interceptors/auth.interceptor';
import { ErrorHandlerInterceptor } from '../interceptors/error-handler.interceptor';
// From @angular/common/http/src/interceptor: allows to chain interceptors
class HttpInterceptorHandler implements HttpHandler {
constructor(
private next: HttpHandler,
private interceptor: HttpInterceptor
) {}
handle(request: HttpRequest<any>): Observable<HttpEvent<any>> {
return this.interceptor.intercept(request, this.next);
}
}
/**
* Allows to override default dynamic interceptors that can be disabled with the HttpService extension.
* Except for very specific needs, you should better configure these interceptors directly in the constructor below
* for better readability.
*
* For static interceptors that should always be enabled (like ApiPrefixInterceptor), use the standard
* HTTP_INTERCEPTORS token.
*/
export const HTTP_DYNAMIC_INTERCEPTORS = new InjectionToken<HttpInterceptor>(
'HTTP_DYNAMIC_INTERCEPTORS'
);
/**
* Extends HttpClient with per request configuration using dynamic interceptors.
*/
@Injectable({
providedIn: 'root'
})
export class HttpService extends HttpClient {
constructor(
private httpHandler: HttpHandler,
private injector: Injector,
@Optional()
@Inject(HTTP_DYNAMIC_INTERCEPTORS)
private interceptors: HttpInterceptor[] = []
) {
super(httpHandler);
if (!this.interceptors) {
// Configure default interceptors that can be disabled here
this.interceptors = [
this.injector.get(ApiPrefixInterceptor),
this.injector.get(AuthInterceptor),
this.injector.get(ErrorHandlerInterceptor),
];
}
}
disableApiPrefix(): HttpService {
return this.removeInterceptor(ApiPrefixInterceptor);
}
disableAuthentication(): HttpService {
return this.removeInterceptor(AuthInterceptor);
}
disableErrorHandling(): HttpService {
return this.removeInterceptor(ErrorHandlerInterceptor);
}
// Override the original method to wire interceptors when triggering the request.
request(method?: any, url?: any, options?: any): any {
const handler = this.interceptors.reduceRight(
(next, interceptor) => new HttpInterceptorHandler(next, interceptor),
this.httpHandler
);
return new HttpClient(handler).request(method, url, options);
}
private removeInterceptor(interceptorType: Function): HttpService {
return new HttpService(
this.httpHandler,
this.injector,
this.interceptors.filter(i => !(i instanceof interceptorType))
);
}
private addInterceptor(interceptor: HttpInterceptor): HttpService {
return new HttpService(
this.httpHandler,
this.injector,
this.interceptors.concat([interceptor])
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment