Created
February 18, 2019 18:57
-
-
Save djabif/c45f54fa8fc66a4ed228bd841a5dd152 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Observable, ReplaySubject } from 'rxjs'; | |
import { first, delay } from 'rxjs/operators'; | |
import { environment } from '../../environments/environment'; | |
export class SubjectFetch<T> { | |
private _subject: ReplaySubject<T>; | |
private _observable: Observable<T>; | |
// We wait on purpose 2 secs on local environment when fetching from json to simulate the backend roundtrip. | |
// However, in production you should remove this delay. | |
private networkDelay = (environment && environment.shell && environment.shell.networkDelay) ? environment.shell.networkDelay : 0; | |
// To debug shell styles, change configuration in the environment.ts file | |
private debugMode = (environment && environment.shell && environment.shell.debug) ? environment.shell.debug : false; | |
constructor(shellModel: T, fetchDataObservable: Observable<T>) { | |
this._subject = new ReplaySubject<T>(); | |
this._observable = this._subject.asObservable(); | |
// Send the mock | |
this._subject.next(shellModel); | |
// Immediately after fetch data from endpoint | |
fetchDataObservable.pipe( | |
delay(this.networkDelay), | |
// Prevent the need to unsubscribe because .first() completes the observable | |
first() | |
).subscribe((fetchedData: T) => { | |
if (!this.debugMode) { | |
this._subject.next(fetchedData); | |
} | |
}); | |
} | |
public get observable(): Observable<T> { | |
return this._observable; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Injectable } from '@angular/core'; | |
import { HttpClient } from '@angular/common/http'; | |
import { Observable } from 'rxjs'; | |
import { SubjectFetch } from '../utils/subject-fetch'; | |
import { TravelListingModel } from './listing/travel-listing.model'; | |
import { TravelDetailsModel } from './details/travel-details.model'; | |
@Injectable() | |
export class TravelService { | |
private _listingCache: SubjectFetch<TravelListingModel>; | |
private _detailsCache: SubjectFetch<TravelDetailsModel>; | |
constructor(private http: HttpClient) { } | |
public list(): Observable<TravelListingModel> { | |
// Use cache if we have it. | |
if (!this._listingCache) { | |
// Initialize the model specifying that it is a shell model | |
const listingShellModel: TravelListingModel = new TravelListingModel(true); | |
this._listingCache = new SubjectFetch(listingShellModel, this.listingDataObservable()); | |
} | |
return this._listingCache.observable; | |
} | |
private listingDataObservable(): Observable<TravelListingModel> { | |
return this.http.get<TravelListingModel>('./assets/sample-data/travel/listing.json'); | |
} | |
public details(): Observable<TravelDetailsModel> { | |
// Use cache if we have it. | |
if (!this._detailsCache) { | |
// Initialize the model specifying that it is a shell model | |
const detailsShellModel: TravelDetailsModel = new TravelDetailsModel(true); | |
this._detailsCache = new SubjectFetch(detailsShellModel, this.detailsDataObservable()); | |
} | |
return this._detailsCache.observable; | |
} | |
private detailsDataObservable(): Observable<TravelDetailsModel> { | |
return this.http.get<TravelDetailsModel>('./assets/sample-data/travel/details.json'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment