WIP: Extract interaction with store into service
[examples/angular-tour-of-heroes] / src / app / vorgang.service.ts
1 import { Injectable } from '@angular/core';
2 import { HttpClient, HttpHeaders } from '@angular/common/http';
3 import { Observable, of, EMPTY } from 'rxjs';
4 import { catchError, map, tap } from 'rxjs/operators';
5 import { select, Store } from '@ngrx/store';
6 import { Vorgang } from './vorgang';
7 import { increment, decrement, reset } from './actions/vorgang';
8 import { State } from './reducers/vorgang';
9
10
11 @Injectable({
12   providedIn: 'root'
13 })
14 export class VorgangService {
15
16   gpsUrl = 'http://localhost:1991/las/';  // URL to web api
17   httpOptions = {
18     headers: new HttpHeaders({
19       'Content-Type': 'text/plain',
20       'Accept': 'application/json'
21     })
22   };
23
24   constructor(
25     private http: HttpClient,
26     private store: Store<{ vorgang: State }>) { }
27
28   /** POST: Einen neuen Vorgang erzeugen */
29   create(vorgang: Vorgang): Observable<Vorgang> {
30     return this
31       .http
32       .post<Vorgang>(
33         this.getUrlSave(vorgang.vbId),
34         vorgang.zustand,
35         this.httpOptions)
36       .pipe(
37         tap((result: Vorgang) => this.log(`Result for ${JSON.stringify(vorgang)}: ${JSON.stringify(result)}`)),
38         catchError(this.handleError<Vorgang>('create')));
39   }
40
41   getUrlSave(vbId: string): string {
42     return this.gpsUrl + vbId + '/save';
43   }
44
45   increment() {
46     this.store.dispatch(increment());
47   }
48
49   decrement() {
50     this.store.dispatch(decrement());
51   }
52
53   reset() {
54     this.store.dispatch(reset());
55   }
56
57   Observable<number> observe() {
58     return this.store.pipe(select('vorgang'), map(vorgang => vorgang.counter));
59   }
60
61   /**
62    * Handle Http operation that failed.
63    * Let the app continue.
64    * @param operation - name of the operation that failed
65    * @param result - optional value to return as the observable result
66    */
67   private handleError<T>(operation = 'operation', result?: T) {
68     return (error: any): Observable<T> => {
69
70       // TODO: send the error to remote logging infrastructure
71       console.error(error); // log to console instead
72
73       // TODO: better job of transforming error for user consumption
74       this.log(`${operation} failed: ${error.message}`);
75
76       // Let the app keep running by returning an empty result.
77       if (result === undefined) {
78         return EMPTY as Observable<T>;
79       } else {
80         return of(result as T);
81       }
82     };
83   }
84
85   private log(message: string) {
86     console.log(message);
87   }
88 }