import { Injectable } from '@angular/core' ; import { Store } from '@ngrx/store' ; import { BehaviorSubject , Observable } from 'rxjs' ; import { combineLatest } from 'rxjs/operators' ; import { Hero , ToastService } from '../core' ; import { HeroesDataService } from '../data-services' ; import { FilterObserver } from '../shared/filter' ; import * as fromStore from '../store' ; @ Injectable ( ) export class HeroService { constructor ( private heroesDataService , private store , private toastService ) { this . createSelectors$ ( ) ; this . wireFilteredEntities ( ) ; } /** live list of cached Heroes */ entities$ : Observable < Hero [ ] > ; /** Entities filtered by those criteria */ filteredEntities$ : Observable < Hero [ ] > ; /** User's filter pattern */ filterObserver : FilterObserver ; /** true when getting all the entities */ loading$ : Observable < boolean > ; createSelectors$ ( ) { const selectors$ = fromStore . createHeroesSelectors$ ( this . store ) ; this . entities$ = selectors$ . heroes$ ; this . loading$ = selectors$ . loading$ ; } /** Dispatch GetAll request action */ getAll ( ) { const action = new fromStore . LoadHeroes ( ) ; this . store . dispatch ( action ) ; } /** Dispatch add hero request action */ add ( hero ) { if ( hero ) { const action = new fromStore . AddHero ( hero ) ; this . store . dispatch ( action ) ; } } /** Dispatch hero delete-by-id request action */ delete ( id ) { if ( id ) { const action = new fromStore . DeleteHero ( id ) ; this . store . dispatch ( action ) ; } } /** Dispatch hero update request action */ update ( hero ) { if ( hero ) { const action = new fromStore . UpdateHero ( hero ) ; this . store . dispatch ( action ) ; } } wireFilteredEntities ( ) { const filterObserver = new BehaviorSubject ( '' ) ; this . filterObserver = { filter$ : filterObserver . asObservable ( ) , setFilter : filterValue => filterObserver . next ( filterValue ) } ; this . filteredEntities$ = this . filterObserver . filter$ . pipe ( combineLatest ( this . entities$ , this . filterProjector ) ) ; } protected filterProjector ( filterValue , entities ) { const regEx = filterValue ? new RegExp ( filterValue , 'i' ) : undefined ; return regEx ? entities . filter ( ( e ) => e . name && e . name . match ( regEx ) ) : entities ; } }