Created
February 7, 2018 16:10
-
-
Save sinedied/46f9b3cf5cbd04fa452d1446edc6006d to your computer and use it in GitHub Desktop.
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/Observable'; | |
import { ErrorHandlerInterceptor } from './error-handler.interceptor'; | |
import { CacheInterceptor } from './cache.interceptor'; | |
// HttpClient is declared in a re-exported module, so we have to extend the original module to make it work properly | |
// (see https://github.com/Microsoft/TypeScript/issues/13897) | |
declare module '@angular/common/http/src/client' { | |
// Augment HttpClient with the configuration methods from HttpService for convenience, | |
// allowing to inject HttpService in place of HttpClient and still use the extension methods | |
export interface HttpClient { | |
cache(forceUpdate?: boolean): HttpClient; | |
skipErrorHandler(): HttpClient; | |
} | |
} | |
/** | |
* Allow to override default 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. | |
*/ | |
export const HTTP_DYNAMIC_INTERCEPTORS = new InjectionToken<HttpInterceptor>('HTTP_DYNAMIC_INTERCEPTORS'); | |
/** | |
* Provides a base for HTTP client extension. | |
* The default extension adds support for API prefixing, request caching and default error handler. | |
*/ | |
@Injectable() | |
export class HttpService extends HttpClient { | |
constructor(private httpHandler: HttpHandler, | |
private injector: Injector, | |
@Optional() @Inject(HTTP_DYNAMIC_INTERCEPTORS) private interceptors: HttpInterceptor[] | null) { | |
super(httpHandler); | |
if (!this.interceptors) { | |
// Configure default interceptors that can be disabled here | |
this.interceptors = [this.injector.get(ErrorHandlerInterceptor)]; | |
} | |
} | |
/** | |
* Enables caching for this request. | |
* @param {boolean} forceUpdate Forces request to be made and updates cache entry. | |
* @return {HttpClient} The new instance. | |
*/ | |
cache(forceUpdate?: boolean): HttpClient { | |
const cacheInterceptor = this.injector.get(CacheInterceptor).configure({ update: forceUpdate }); | |
return this.addInterceptor(cacheInterceptor); | |
} | |
/** | |
* Skips default error handler for this request. | |
* @return {HttpClient} The new instance. | |
*/ | |
skipErrorHandler(): HttpClient { | |
return this.removeInterceptor(ErrorHandlerInterceptor); | |
} | |
/** | |
* Wires the interceptors when triggering the requests. | |
*/ | |
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]) | |
); | |
} | |
} | |
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); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment