Created
November 24, 2019 17:06
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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