import { Injectable } from '@angular/core' ; import { HttpClient , HttpErrorResponse , HttpHeaders } from '@angular/common/http' ; import { Observable } from 'rxjs/Observable' ; import { ErrorObservable } from 'rxjs/observable/ErrorObservable' ; import { of } from 'rxjs/observable/of' ; import { catchError , tap } from 'rxjs/operators' ; import { IProduct } from './product' ; @ Injectable ( ) export class ProductService { private productsUrl = 'api/products' ; private products : IProduct [ ] ; currentProduct : IProduct ; constructor ( private http ) { } getProducts ( ) { if ( this . products ) { return of ( this . products ) ; } return this . http . get < IProduct [ ] > ( this . productsUrl ) . pipe ( tap ( data => console . log ( JSON . stringify ( data ) ) ) , tap ( data => this . products = data ) , catchError ( this . handleError ) ) ; } getProduct ( id ) { if ( id === 0 ) { return of ( this . initializeProduct ( ) ) ; } if ( this . products ) { const foundItem = this . products . find ( item => item . id === id ) ; if ( foundItem ) { return of ( foundItem ) ; } } const url = `${ this . productsUrl }/${ id }` ; return this . http . get < IProduct > ( url ) . pipe ( tap ( data => console . log ( 'Data: ' + JSON . stringify ( data ) ) ) , catchError ( this . handleError ) ) ; } saveProduct ( product ) { const headers = new HttpHeaders ( { 'Content-Type' : 'application/json' } ) ; if ( product . id === 0 ) { return this . createProduct ( product , headers ) ; } return this . updateProduct ( product , headers ) ; } deleteProduct ( id ) { const headers = new HttpHeaders ( { 'Content-Type' : 'application/json' } ) ; const url = `${ this . productsUrl }/${ id }` ; return this . http . delete < IProduct > ( url , { headers : headers } ) . pipe ( tap ( data => console . log ( 'deleteProduct: ' + id ) ) , tap ( data => { const foundIndex = this . products . findIndex ( item => item . id === id ) ; if ( foundIndex > - 1 ) { this . products . splice ( foundIndex , 1 ) ; this . currentProduct = null ; } } ) , catchError ( this . handleError ) ) ; } private createProduct ( product , headers ) { product . id = null ; return this . http . post < IProduct > ( this . productsUrl , product , { headers : headers } ) . pipe ( tap ( data => console . log ( 'createProduct: ' + JSON . stringify ( data ) ) ) , tap ( data => { this . products . push ( data ) ; this . currentProduct = data ; } ) , catchError ( this . handleError ) ) ; } private updateProduct ( product , headers ) { const url = `${ this . productsUrl }/${ product . id }` ; return this . http . put < IProduct > ( url , product , { headers : headers } ) . pipe ( tap ( data => console . log ( 'updateProduct: ' + product . id ) ) , catchError ( this . handleError ) ) ; } private initializeProduct ( ) { return { 'id' : 0 , productName : '' , productCode : '' , category : '' , tags : [ ] , releaseDate : '' , price : 0 , description : '' , starRating : 0 , imageUrl : '' } ; } private handleError ( err ) { let errorMessage ; if ( err . error instanceof Error ) { errorMessage = `An error occurred: ${ err . error . message }` ; } else { errorMessage = `Backend returned code ${ err . status }, body was: ${ err . error }` ; } console . error ( err ) ; return new ErrorObservable ( errorMessage ) ; } }