From 91050c51fa32b6e57d711199997829d0f4fc4c62 Mon Sep 17 00:00:00 2001 From: Ed Morales Date: Tue, 13 Sep 2016 07:19:46 -0700 Subject: [PATCH] feature(http): new http (#62) * removed provideInterceptors() * polished httpInterceptorService and fixed bugs in interceptor pipeline * change properties in IRestQuery to any type * added ngModule to http module, and provided interceptors with forRoot() to be inline with angular * updated docs with ngmodule notation for http module * reword example to setup in http module * created http.module.ts for CovalentHttpModule * updated README.md --- src/app/app.module.ts | 2 + .../components/http/http.component.html | 23 ++-- src/platform/http/README.md | 24 ++-- src/platform/http/http-interceptor.service.ts | 108 +++++------------- src/platform/http/http-rest.service.ts | 2 +- src/platform/http/http.module.ts | 32 ++++++ src/platform/http/index.ts | 3 +- 7 files changed, 96 insertions(+), 98 deletions(-) create mode 100644 src/platform/http/http.module.ts diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4aa402c02c..28578cc242 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -11,6 +11,7 @@ import { appRoutes, appRoutingProviders } from './app.routes'; import { CovalentCoreModule, TD_LOADING_ENTRY_COMPONENTS } from '../platform/core'; import { CovalentFileModule } from '../platform/file-upload'; import { CovalentHighlightModule } from '../platform/highlight'; +import { CovalentHttpModule } from '../platform/http'; import { CovalentMarkdownModule } from '../platform/markdown'; import { CovalentJsonFormatterModule } from '../platform/json-formatter'; import { CovalentChipsModule } from '../platform/chips'; @@ -27,6 +28,7 @@ import { CovalentChipsModule } from '../platform/chips'; StyleGuideModule, CovalentCoreModule.forRoot(), CovalentFileModule.forRoot(), + CovalentHttpModule.forRoot(), CovalentHighlightModule, CovalentMarkdownModule, CovalentJsonFormatterModule, diff --git a/src/app/components/components/http/http.component.html b/src/app/components/components/http/http.component.html index 683bf61ec4..1ca8866ac0 100644 --- a/src/app/components/components/http/http.component.html +++ b/src/app/components/components/http/http.component.html @@ -24,8 +24,8 @@

{{attr.name}}: {{attr.type}}

-

Example:

-

Typescript:

+

Setup:

+

Create your custom interceptors by implementing [IHttpInterceptor]:

Example: } ]]> -

Bootstrap interceptor providers:

+

Then, import the [CovalentHttpModule] using the forRoot() method with the desired interceptors in your NgModule:

After that, just inject [HttpInterceptorService] and use it for your requests.

diff --git a/src/platform/http/README.md b/src/platform/http/README.md index fe17503ce3..0edd2eb811 100644 --- a/src/platform/http/README.md +++ b/src/platform/http/README.md @@ -29,7 +29,9 @@ export interface IHttpInterceptor { ``` Every method is optional, so you can just implement the ones that are needed. -Example: +## Setup + +Create your custom interceptors by implementing [IHttpInterceptor]: ```typescript import { Injectable } from '@angular/core'; @@ -56,17 +58,21 @@ export class CustomInterceptor implements IHttpInterceptor { ``` -Also, you need to bootstrap the interceptor providers +Then, import the [CovalentHttpModule] using the forRoot() method with the desired interceptors in your NgModule: ```typescript -import { HTTP_PROVIDERS } from '@angular/http'; -import { provideInterceptors } from '@covalent/http'; +import { HttpModule } from '@angular/http'; +import { CovalentHttpModule } from '@covalent/http'; import { CustomInterceptor } from 'dir/to/interceptor'; - -bootstrap(AppComponent, [ - HTTP_PROVIDERS, - provideInterceptors([CustomInterceptor]), -]); +@NgModule({ + imports: [ + HttpModule, /* or CovalentCoreModule.forRoot() */ + CovalentHttpModule.forRoot([CustomInterceptor]), + ... + ], + ... +}) +export class MyModule {} ``` After that, just inject [HttpInterceptorService] and use it for your requests. diff --git a/src/platform/http/http-interceptor.service.ts b/src/platform/http/http-interceptor.service.ts index 50e7f950bc..1aa7d88664 100644 --- a/src/platform/http/http-interceptor.service.ts +++ b/src/platform/http/http-interceptor.service.ts @@ -1,4 +1,4 @@ -import { Injectable, Type, ValueProvider, Injector } from '@angular/core'; +import { Injectable, Type, Injector } from '@angular/core'; import { Http, RequestOptionsArgs, Response, Request } from '@angular/http'; import { Observable } from 'rxjs/Observable'; @@ -13,127 +13,79 @@ export interface IHttpInterceptor { @Injectable() export class HttpInterceptorService { - requestInterceptors: IHttpInterceptor[] = []; + private _requestInterceptors: IHttpInterceptor[] = []; constructor(private _http: Http, private _injector: Injector, requestInterceptors: Type[]) { requestInterceptors.forEach((interceptor: Type) => { - this.requestInterceptors.push(_injector.get(interceptor)); + this._requestInterceptors.push(_injector.get(interceptor)); }); } request(url: string | Request, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.request(url, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.request(url, this._requestResolve(options))); } delete(url: string, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.delete(url, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.delete(url, this._requestResolve(options))); } get(url: string, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.get(url, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.get(url, this._requestResolve(options))); } head(url: string, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.head(url, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.head(url, this._requestResolve(options))); } patch(url: string, data: any, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.patch(url, data, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.patch(url, data, this._requestResolve(options))); } post(url: string, data: any, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.post(url, data, options) - .do((response: Response) => { - return this._responseResolve(response); - }).catch((error: Response) => { - return this._errorResolve(error); - }); + return this._setupRequest(this._http.post(url, data, this._requestResolve(options))); } put(url: string, data: any, options: RequestOptionsArgs = {}): Observable { - this._requestConfig(options); - return this._http.put(url, data, options) - .do((response: Response) => { - return this._responseResolve(response); + return this._setupRequest(this._http.put(url, data, this._requestResolve(options))); + } + + private _setupRequest(responseObservable: Observable): Observable { + return new Observable((subscriber: Subscriber) => { + responseObservable.do((response: Response) => { + subscriber.next(this._responseResolve(response)); }).catch((error: Response) => { - return this._errorResolve(error); - }); + return new Observable(() => { + subscriber.error(this._responseErrorResolve(error)); + }); + }).subscribe(); + }); } - private _requestConfig(requestOptions: RequestOptionsArgs): void { - this.requestInterceptors.forEach((interceptor: IHttpInterceptor) => { + private _requestResolve(requestOptions: RequestOptionsArgs): RequestOptionsArgs { + this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => { if (interceptor.onRequest) { requestOptions = interceptor.onRequest(requestOptions); } }); + return requestOptions; } - private _responseResolve(response: Response): Observable { - this.requestInterceptors.forEach((interceptor: IHttpInterceptor) => { + private _responseResolve(response: Response): Response { + this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => { if (interceptor.onResponse) { response = interceptor.onResponse(response); } }); - return new Observable((subscriber: Subscriber) => { - subscriber.next(response); - }); + return response; } - private _errorResolve(error: Response): Observable { - this.requestInterceptors.forEach((interceptor: IHttpInterceptor) => { + private _responseErrorResolve(error: Response): Response { + this._requestInterceptors.forEach((interceptor: IHttpInterceptor) => { if (interceptor.onResponseError) { error = interceptor.onResponseError(error); } }); - return new Observable((subscriber: Subscriber) => { - subscriber.error(error); - }); + return error; } } - -export function provideInterceptors(requestInterceptors: Type[] = []): any[] { - let providers: any[] = []; - requestInterceptors.forEach((interceptor: Type) => { - providers.push(interceptor); - }); - providers.push({ - provide: HttpInterceptorService, - useFactory: (http: Http, injector: Injector): HttpInterceptorService => { - return new HttpInterceptorService(http, injector, requestInterceptors); - }, - deps: [Http, Injector], - }); - return providers; -} diff --git a/src/platform/http/http-rest.service.ts b/src/platform/http/http-rest.service.ts index 74608a9046..35d2eeeb9d 100644 --- a/src/platform/http/http-rest.service.ts +++ b/src/platform/http/http-rest.service.ts @@ -14,7 +14,7 @@ export interface IRestConfig { } export interface IRestQuery { - [key: string]: boolean | number | string; + [key: string]: any; } export interface IHttp { diff --git a/src/platform/http/http.module.ts b/src/platform/http/http.module.ts new file mode 100644 index 0000000000..85f02379ed --- /dev/null +++ b/src/platform/http/http.module.ts @@ -0,0 +1,32 @@ +import { NgModule, ModuleWithProviders, Type, Injector } from '@angular/core'; +import { HttpModule, Http } from '@angular/http'; + +import { HttpInterceptorService } from './http-interceptor.service'; + +@NgModule({ + imports: [ + HttpModule, + ], + providers: [ + HttpInterceptorService, + ], +}) +export class CovalentHttpModule { + static forRoot(requestInterceptors: Type[] = []): ModuleWithProviders { + let providers: any[] = []; + requestInterceptors.forEach((interceptor: Type) => { + providers.push(interceptor); + }); + providers.push({ + provide: HttpInterceptorService, + useFactory: (http: Http, injector: Injector): HttpInterceptorService => { + return new HttpInterceptorService(http, injector, requestInterceptors); + }, + deps: [Http, Injector], + }); + return { + ngModule: CovalentHttpModule, + providers: providers, + }; + } +} diff --git a/src/platform/http/index.ts b/src/platform/http/index.ts index 5279a7bef5..47d596a918 100644 --- a/src/platform/http/index.ts +++ b/src/platform/http/index.ts @@ -1,2 +1,3 @@ export { RESTService, IRestTransform, IRestConfig, IRestQuery, IHttp } from './http-rest.service'; -export { IHttpInterceptor, HttpInterceptorService, provideInterceptors } from './http-interceptor.service'; +export { IHttpInterceptor, HttpInterceptorService } from './http-interceptor.service'; +export { CovalentHttpModule } from './http.module';