UNPKG

ngrx-model

Version:

Model classes for integrating ngrx store with a REST API

178 lines (157 loc) 6.31 kB
import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; import { HttpUtility } from '../http/http.service'; import { IConverter, ConverterService } from './converters.service'; export interface IRequestOptions<TDataType> { endpoint: string; useMock?: boolean; logRequests?: boolean; transform?: IConverter<TDataType> | { [index: string]: IConverter<any> } } export interface IGetListOptions<TDataType> extends IRequestOptions<TDataType> { params: any; getMockData?: { (): TDataType[] }; } export interface IGetItemOptions<TDataType> extends IRequestOptions<TDataType> { getMockData?: { (): TDataType }; } export interface ICreateOptions<TDataType> extends IRequestOptions<TDataType> { domainObject: TDataType; addMockData?: { (data: TDataType): void }; } export interface IUpdateOptions<TDataType> extends IRequestOptions<TDataType> { domainObject: TDataType; updateMockData?: { (data: TDataType): void }; } export interface IDeleteOptions<TDataType> extends IRequestOptions<TDataType> { domainObject: TDataType; removeMockData?: { (data: TDataType): void }; } export interface ISearchResult<TDataType> { dataSet: TDataType[]; } export interface IRequestService { getList<TDataType>(options: IGetListOptions<TDataType>): Observable<TDataType[]>; search<TDataType, TResultType>(options: IGetListOptions<TDataType>): Observable<TResultType>; getItem<TDataType>(options: IGetItemOptions<TDataType>): Observable<TDataType>; create<TDataType>(options: ICreateOptions<TDataType>): Observable<TDataType>; update<TDataType>(options: IUpdateOptions<TDataType>): Observable<TDataType>; delete<TDataType>(options: IDeleteOptions<TDataType>): Observable<void>; } @Injectable() export class RequestService implements IRequestService { private http: HttpUtility; private converterService: ConverterService; constructor(http: HttpUtility, converterService: ConverterService) { this.http = http; this.converterService = converterService; } getList<TDataType>(options: IGetListOptions<TDataType>): Observable<TDataType[]> { let request: Observable<TDataType[]>; if (options.useMock) { request = Observable.of(options.getMockData()); } else { request = this.http.get<TDataType[]>(options.endpoint, options.params); } return request.map((data: TDataType[]): TDataType[] => { data = this.converterService.applyTransform(data, options.transform, false); if (options.logRequests) { this.log('getList', options.params, data, options.endpoint, options.useMock); } return data; }); } search<TDataType, TResultType extends ISearchResult<TDataType>>(options: IGetListOptions<TDataType>): Observable<TResultType> { let request: Observable<TResultType>; if (options.useMock) { request = Observable.of<TResultType>(<any>{ dataSet: options.getMockData(), }); } else { request = this.http.post<TResultType>(options.endpoint, options.params); } return request.map((result: TResultType): TResultType => { result.dataSet = this.converterService.applyTransform(result.dataSet, options.transform, false); if (options.logRequests) { this.log('search', options.params, result, options.endpoint, options.useMock); } return result; }) } getItem<TDataType>(options: IGetItemOptions<TDataType>): Observable<TDataType> { let promise: Observable<TDataType>; if (options.useMock) { promise = Observable.of(options.getMockData()); } else { promise = this.http.get<TDataType>(options.endpoint); } return promise.map((data: TDataType): TDataType => { data = this.converterService.applyTransform(data, options.transform, false); if (options.logRequests) { this.log('get', null, data, options.endpoint, options.useMock); } return data; }); } create<TDataType>(options: ICreateOptions<TDataType>): Observable<TDataType> { let promise: Observable<TDataType>; options.domainObject = this.converterService.applyTransform(options.domainObject, options.transform, true); if (options.useMock) { options.addMockData(options.domainObject); promise = Observable.of(options.domainObject); } else { promise = this.http.post<TDataType>(options.endpoint, options.domainObject); } return promise.map((data: TDataType): TDataType => { data = this.converterService.applyTransform(data, options.transform, false); if (options.logRequests) { this.log('create', options.domainObject, data, options.endpoint, options.useMock); } return data; }); } update<TDataType>(options: IUpdateOptions<TDataType>): Observable<TDataType> { let promise: Observable<TDataType>; options.domainObject = this.converterService.applyTransform(options.domainObject, options.transform, true); if (options.useMock) { options.updateMockData(options.domainObject) promise = Observable.of(options.domainObject); } else { promise = this.http.put<TDataType>(options.endpoint, options.domainObject); } return promise.map((data: TDataType): TDataType => { data = this.converterService.applyTransform(data, options.transform, false); if (options.logRequests) { this.log('update', options.domainObject, data, options.endpoint, options.useMock); } return data; }); } delete<TDataType>(options: IDeleteOptions<TDataType>): Observable<void> { let promise: Observable<void>; if (options.useMock) { options.removeMockData(options.domainObject); promise = Observable.empty<void>(); } else { promise = this.http.delete(options.endpoint); } return promise.map((): void => { if (options.logRequests) { this.log('delete', options.domainObject, null, options.endpoint, options.useMock); } }); } private log(requestName: string, params: any, data: any, endpoint: string, useMock: boolean): void { let mockString = useMock ? 'Mocked ' : ''; let endpointString = endpoint == null ? 'unspecified' : endpoint; console.log(mockString + requestName + ' for endpoint ' + endpointString + ':'); if (params != null) { console.log('params:'); console.log(params); } if (data != null) { console.log('data:'); console.log(data); } } }