All files / src/app/dashboard measure.service.ts

100% Statements 63/63
85.71% Branches 6/7
100% Functions 20/20
100% Lines 56/56
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x 1x 1x 1x 1x       1x 1x 1x 1x 1x     1x   1x 1x 1x     7x 7x 7x 7x 7x 7x     3x 3x 2x 2x   1x 1x         2x 2x     2x 2x 1x 1x       3x 3x     3x   6x 3x           1x 12x 6x     1x 3x 3x 3x 3x     1x 9x 9x 3x   9x     6x       2x 1x 1x 1x     1x  
import '../rxjs-extensions';
import { Injectable} from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { NgRedux, select, select$ } from '@angular-redux/store';
 
import { IMeasure, IMeasureUpdate } from '../model/measure.model';
import { IAppState } from '../store/state/AppState';
import { ValidationsDataService } from '../linqpad-review-pages/validations/services/validations-data.service';
import { ReferentialsDataService } from '../linqpad-review-pages/referentials/services/referentials-data.service';
import { ClinicsDataService } from '../linqpad-review-pages/clinics/services/clinics-data.service';
import { ifNull } from '../store/selector-helpers/selector-helpers';
import { MeasureActions } from './measure.actions';
 
@Injectable()
export class MeasureService {
 
  @select('measures') measures$: Observable<IMeasure[]>;
  @select('pages') pages$: Observable<any>;
  @select(['config', 'baseDataUrl']) baseDataUrl$: Observable<string>;
 
  constructor(
    private http: Http,
    private ngRedux: NgRedux<IAppState>,
    private validationsDataService: ValidationsDataService,
    private referentialsDataService: ReferentialsDataService,
    private clinicsDataService: ClinicsDataService,
    private measureActions: MeasureActions,
  ) {}
 
  public initializeMeasures() {
    ifNull(this.measures$, () => {
      this.measureActions.initializeMeasuresRequest();
      this.getMeasures()
        .subscribe(
          (measures) => { this.measureActions.initializeMeasuresSuccess(measures); },
          (error) => { this.measureActions.initializeMeasuresFailed(error); },
        );
    });
  }
 
  private getMeasures(): Observable<IMeasure[]> {
    return this.baseDataUrl$
      .waitFor$()
      .mergeMap(baseDataUrl => {
        const url = baseDataUrl + 'InitialMeasures.json';
        return this.http.get(url)
          .map(response => response.json().measures)
          .catch(error => this.handleError(error, 'getInitialMeasures'));
      });
  }
 
  public updateMeasures() {
    this.measures$
      .waitFor$()
      .subscribe( measures => {
        this.getAllMeasureUpdates()
          .subscribe(measureUpdate => {
            if (this.hasChanged(measures, measureUpdate)) {
              this.measureActions.updateMeasure(measureUpdate);
            }
          });
      });
  }
 
  private hasChanged(prevMeasures, newMeasure) {
    const oldState = prevMeasures.find(m => m.id === newMeasure.id);
    return !oldState || oldState.metric !== newMeasure.metric || oldState.color !== newMeasure.color;
  }
 
  private getAllMeasureUpdates(): Observable<IMeasureUpdate> {
    const validationMeasure$ = this.getMeasure('validations', this.validationsDataService).take(1);
    const referentialsMeasure$ = this.getMeasure('referentials', this.referentialsDataService).take(1);
    const clinicsMeasure$ = this.getMeasure('clinics', this.clinicsDataService).take(1);
    return validationMeasure$.concat(referentialsMeasure$, clinicsMeasure$);
  }
 
  private getMeasure(measureId, dataService): Observable<IMeasureUpdate> {
    const filesSelector$ = this.ngRedux.select(['pages', measureId, 'files']);
    ifNull(filesSelector$, () => {
      dataService.initializeList();
    });
    return filesSelector$
      .waitFor$()
      .mergeMap(files => {
        return dataService.getMeasure();
      });
  }
 
  private handleError(error: any, method: string, EmethodArgs = null) {
    const msg = `${this.constructor.name}.${method}: ${error}. Method args: ${JSON.stringify(methodArgs)}`;
    console.error(msg);
    return Observable.throw(error);
  }
 
}