Skip to content

Instantly share code, notes, and snippets.

@djabif
Created February 18, 2019 18:57
Show Gist options
  • Save djabif/c45f54fa8fc66a4ed228bd841a5dd152 to your computer and use it in GitHub Desktop.
Save djabif/c45f54fa8fc66a4ed228bd841a5dd152 to your computer and use it in GitHub Desktop.
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;
}
}
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