import { HttpClient , HttpErrorResponse , HttpParams } from '@angular/common/http' ; import { environment } from '@env/environment' ; import { format } from 'date-fns' ; import { BehaviorSubject , Observable , throwError } from 'rxjs' ; import { catchError , finalize , retry } from 'rxjs/operators' ; import { Entity } from './entity.model' ; export interface Filter { [ name ] : string | string [ ] ; } export abstract class EntityService < T extends Entity > { protected readonly baseUrl = environment . API_BASE_URL ; protected loadingSubject = new BehaviorSubject < boolean > ( false ) ; public loading$ = this . loadingSubject . asObservable ( ) ; protected abstract entityPath : string ; constructor ( protected httpClient ) { } getById ( id ) { return this . httpClient . get < T > ( `${ this . baseUrl }/${ this . entityPath }/${ id }` ) . pipe ( catchError ( this . handleError ) ) ; } findAll ( filter , order = 'DESC' , skip = 0 , take = 100 ) { this . loadingSubject . next ( true ) ; return this . httpClient . get < T [ ] > ( `${ this . baseUrl }/${ this . entityPath }` , { params : new HttpParams ( ) . set ( 'filter' , 'filter TODO' ) . set ( 'order' , order ) . set ( 'skip' , skip . toString ( ) ) . set ( 'take' , take . toString ( ) ) , } ) . pipe ( retry ( 3 ) , catchError ( this . handleError ) , finalize ( ( ) => this . loadingSubject . next ( false ) ) ) ; } getAll ( ) { this . loadingSubject . next ( true ) ; return this . httpClient . get < T [ ] > ( `${ this . baseUrl }/${ this . entityPath }` ) . pipe ( retry ( 3 ) , catchError ( this . handleError ) , finalize ( ( ) => this . loadingSubject . next ( false ) ) ) ; } delete ( id ) { this . loadingSubject . next ( true ) ; return this . httpClient . delete ( `${ this . baseUrl }/${ this . entityPath }/${ id }` ) . pipe ( catchError ( this . handleError ) , finalize ( ( ) => this . loadingSubject . next ( false ) ) ) ; } post ( entity ) { this . loadingSubject . next ( true ) ; return this . httpClient . post ( `${ this . baseUrl }/${ this . entityPath }` , entity ) . pipe ( catchError ( this . handleError ) , finalize ( ( ) => this . loadingSubject . next ( false ) ) ) ; } put ( id , entity ) { console . log ( entity ) ; this . loadingSubject . next ( true ) ; return this . httpClient . put ( `${ this . baseUrl }/${ this . entityPath }/${ id }` , entity ) . pipe ( catchError ( this . handleError ) , finalize ( ( ) => this . loadingSubject . next ( false ) ) ) ; } protected handleError ( error ) { let errorMessage ; if ( typeof error === 'string' ) { errorMessage = error ; } else { if ( error . error instanceof ErrorEvent ) { errorMessage = `An error occurred: ${ error . error . message }` ; } else { errorMessage = `Backend returned code ${ error . status }, with body ${ error . message }` ; } } console . error ( error ) ; return throwError ( errorMessage ) ; } protected convertToJson ( body ) { const temporalFunctionToJson = Date . prototype . toJSON ; Date . prototype . toJSON = function ( ) { return format ( this , 'YYYY-MM-DD' ) ; } ; const jsonBody = JSON . stringify ( body ) ; Date . prototype . toJSON = temporalFunctionToJson ; return jsonBody ; } }