import { Injectable } from '@angular/core'; import { Hero } from './hero'; import { Observable, of } from 'rxjs'; import { MessageService } from './message.service'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { catchError, map, tap } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class HeroService { httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; constructor( private http: HttpClient, private messageService: MessageService) { } /** Log a HeroService message with the MessageService */ private log(message: string) { this.messageService.add(`HeroService: ${message}`) } private heroesUrl = 'api/heroes'; // URL to web api getHeroes(): Observable { return this.http.get(this.heroesUrl) .pipe( catchError(this.handleError('getHeroes', [])) ); } /** GET hero by id. Will 404 if id not found */ getHero(id: number): Observable { const url = `${this.heroesUrl}/${id}`; return this.http.get(url).pipe( tap(_ => this.log(`fetched hero id=${id}`)), catchError(this.handleError(`getHero id=${id}`)) ); } /** PUT: update the hero on the server */ updateHero (hero: Hero): Observable { return this.http.put(this.heroesUrl, hero, this.httpOptions).pipe( tap(_ => this.log(`updated hero id=${hero.id}`)), catchError(this.handleError('updateHero')) ); } addHero (hero: Hero): Observable { return this.http.post(this.heroesUrl, hero, this.httpOptions).pipe( tap((newHero: Hero) => this.log(`added hero w/ id=${newHero.id}`)), catchError(this.handleError('addHero')) ); } /** DELETE: delete the hero from the server */ deleteHero (hero: Hero | number): Observable { const id = typeof hero === 'number' ? hero : hero.id; const url = `${this.heroesUrl}/${id}`; return this.http.delete(url, this.httpOptions).pipe( tap(_ => this.log(`deleted hero id=${id}`)), catchError(this.handleError(`deleteHero id=${id}`)) ); } searchHeroes(term: string): Observable { if (!term.trim()) { // if not search term, return empty hero array. return of([]); } return this.http.get(`${this.heroesUrl}/?name=${term}`).pipe( tap(_ => this.log(`found heroes matching "${term}"`)), catchError(this.handleError('searchHeroes', [])) ); } /** * Handle Http operation that failed. * Let the app continue. * @param operation - name of the operation that failed * @param result - optional value to return as the observable result */ private handleError (operation = 'operation', result?: T) { return (error: any): Observable => { // TODO: send the error to remote logging infrastructure console.error(error); // log to console instead // TODO: better job of transforming error for user consumption this.log(`${operation} failed: ${error.message}`); // Let the app keep running by returning an empty result. return of(result as T); }; } }