import { Injectable } from '@angular/core' ; import { Observable , of , throwError } from 'rxjs' ; import { HttpClient , HttpHeaders , HttpErrorResponse } from '@angular/common/http' ; import { catchError , tap , map } from 'rxjs/operators' ; import { Product } from './product' ; const httpOptions = { headers : new HttpHeaders ( { 'Content-Type' : 'application/json' } ) } ; const apiUrl = "http://localhost:3000/api/v1/products" ; @ Injectable ( { providedIn : 'root' } ) export class ApiService { constructor ( private http ) { } getProducts ( ) { return this . http . get < Product [ ] > ( apiUrl ) . pipe ( tap ( products => console . log ( 'Fetch products' ) ) , catchError ( this . handleError ( 'getProducts' , [ ] ) ) ) ; } getProduct ( id ) { const url = `${ apiUrl }/${ id }` ; return this . http . get < Product > ( url ) . pipe ( tap ( _ => console . log ( `fetched product id=${ id }` ) ) , catchError ( this . handleError < Product > ( `getProduct id=${ id }` ) ) ) ; } addProduct ( product ) { return this . http . post < Product > ( apiUrl , product , httpOptions ) . pipe ( tap ( ( product ) => console . log ( `added product w/ id=${ product . _id }` ) ) , catchError ( this . handleError < Product > ( 'addProduct' ) ) ) ; } updateProduct ( id , product ) { const url = `${ apiUrl }/${ id }` ; return this . http . put ( url , product , httpOptions ) . pipe ( tap ( _ => console . log ( `updated product id=${ id }` ) ) , catchError ( this . handleError < any > ( 'updateProduct' ) ) ) ; } deleteProduct ( id ) { const url = `${ apiUrl }/${ id }` ; return this . http . delete < Product > ( url , httpOptions ) . pipe ( tap ( _ => console . log ( `deleted product id=${ id }` ) ) , catchError ( this . handleError < Product > ( 'deleteProduct' ) ) ) ; } private handleError < T > ( operation = 'operation' , result ? ) { return ( error ) : Observable < T > => { console . error ( error ) ; return of ( result as T ) ; } ; } }