Created
February 21, 2019 22:07
-
-
Save zdennis/8f931f44acd18ac3933e45ce901edcaf to your computer and use it in GitHub Desktop.
Angular: Service-layer caching based on routing / navigation events
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 { | |
Component, | |
OnInit, | |
Input, | |
OnDestroy, | |
ViewChild, | |
} from '@angular/core'; | |
import { Order } from '../../orders/order'; | |
import { Subscription } from 'rxjs'; | |
import { ActivatedRoute, Data } from '@angular/router'; | |
import { IonRefresher } from '@ionic/angular'; | |
import { RouteDataResolutionService, RouteDataResolver } from 'src/app/framework-ext/route-data-resolution.service'; | |
@Component({ | |
selector: 'app-order-list-page', | |
templateUrl: './order-list-page.component.html', | |
styleUrls: ['./order-list-page.component.scss'] | |
}) | |
export class OrderListPageComponent implements OnInit, OnDestroy { | |
@Input() orders: Order[] = []; | |
@ViewChild(IonRefresher) | |
refresher: IonRefresher; | |
private refreshing = false; | |
private routeDataResolver: RouteDataResolver; | |
private subscriptions: Subscription[] = []; | |
constructor( | |
private activatedRoute: ActivatedRoute, | |
private routeDataResolutionService: RouteDataResolutionService, | |
) {} | |
ngOnInit() { | |
this.routeDataResolver = this.routeDataResolutionService.resolverFor(this.activatedRoute); | |
this.subscriptions.push( | |
this.routeDataResolver.data.subscribe(data => this.routeDataResolved(data)) | |
); | |
} | |
ngOnDestroy() { | |
this.subscriptions.forEach(s => s.unsubscribe()); | |
} | |
ionViewWillEnter() { | |
this.routeDataResolver.resolve(); | |
} | |
doRefresh() { | |
this.refreshing = true; | |
this.routeDataResolver.resolve(); | |
} | |
routeDataResolved(data: Data) { | |
this.orders = data.orders; | |
if (this.refreshing) { | |
this.refreshing = false; | |
this.refresher.complete(); | |
} | |
} | |
} |
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 { Observable, ReplaySubject } from 'rxjs'; | |
import { Router, NavigationStart, NavigationEnd } from '@angular/router'; | |
@Injectable({ | |
providedIn: 'root' | |
}) | |
export class RouterCacheService { | |
constructor(private router: Router) {} | |
createCacheStore(): RouterCacheStore { | |
return new RouterCacheStore(this.router); | |
} | |
} | |
export class RouterCacheStore { | |
private _cache: { [k: string]: any } = {}; | |
private _shouldCache = false; | |
constructor(private router: Router) { | |
this.router.events.subscribe(event => { | |
if (event instanceof NavigationStart) { | |
this._shouldCache = true; | |
} else if (event instanceof NavigationEnd) { | |
this._shouldCache = false; | |
this._cache = {}; | |
} | |
}); | |
} | |
cacheObservable<T>(key, fn: () => Observable<T>): Observable<T> { | |
if (!this._shouldCache) { | |
return fn(); | |
} else { | |
const subject = this._cache[key] || new ReplaySubject<T>(1); | |
if (!this._cache.hasOwnProperty(key)) { | |
fn().subscribe( | |
results => { | |
this._cache[key] = subject; | |
subject.next(results); | |
}, | |
error => subject.error(error), | |
() => subject.complete() | |
); | |
} | |
return subject.asObservable(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment