Skip to content
This repository was archived by the owner on Dec 27, 2024. It is now read-only.

Commit 80b2c4b

Browse files
committed
#10 getCachedObservable implemented
1 parent 2e2ba19 commit 80b2c4b

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

src/app/shared/rxjs-imports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'rxjs/add/operator/concatMap';
1010
import 'rxjs/add/operator/delay';
1111
import 'rxjs/add/operator/do';
1212
import 'rxjs/add/operator/map';
13+
import 'rxjs/add/operator/mergeMap';
1314
import 'rxjs/add/operator/publishReplay';
1415
import 'rxjs/add/operator/retryWhen';
1516
import 'rxjs/add/operator/take';

src/app/shared/services/storage.service.spec.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,5 +313,52 @@ describe('StorageService', () => {
313313
done.fail(err);
314314
}
315315
});
316+
317+
describe('getCachedObservable', () => {
318+
it('calls observable if not yet cached', async (done) => {
319+
try {
320+
for (const type of stores) {
321+
322+
const obs = Observable.of('observable called');
323+
await store[type].getCachedObservable('test', obs).toPromise();
324+
expect(await store[type].getItem('test').toPromise()).toBe('observable called', type);
325+
}
326+
done();
327+
} catch (err) {
328+
done.fail(err);
329+
}
330+
});
331+
332+
it('returns cached value instead of observable', async (done) => {
333+
try {
334+
for (const type of stores) {
335+
336+
const obs = Observable.of('observable called');
337+
await store[type].setItem('test', 'cached value');
338+
expect(await store[type].getCachedObservable('test', obs).toPromise()).toBe('cached value', type);
339+
}
340+
done();
341+
} catch (err) {
342+
done.fail(err);
343+
}
344+
});
345+
346+
it('returns observable value after cache expiration', async (done) => {
347+
try {
348+
for (const type of stores) {
349+
const obs = Observable.of('observable called');
350+
await store[type].setItem('test', 'cached value', 1);
351+
expect(await store[type].getCachedObservable('test', obs).toPromise()).toBe('cached value', type);
352+
353+
await new Promise((resolve) => setTimeout(resolve, 1010));
354+
expect(await store[type].getCachedObservable('test', obs).toPromise()).toBe('observable called', type);
355+
356+
}
357+
done();
358+
} catch (err) {
359+
done.fail(err);
360+
}
361+
});
362+
});
316363
});
317364
});

src/app/shared/services/storage.service.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ export abstract class BaseStorageService {
140140
*/
141141
abstract getStorageEngine(): Observable<StorageEngine>;
142142

143+
getCachedObservable<T>(key: string, observable: Observable<T>, cacheTTL = 0, gc = false): Observable<T> {
144+
return this
145+
.getItem(key)
146+
.map((val) => val || null)
147+
.flatMap((val: any) => (val !== null)
148+
? Observable.of(val)
149+
: observable.flatMap((obsVal: any) => this.setItem(key, obsVal, cacheTTL, gc)));
150+
}
151+
143152
/**
144153
* Gets an observable that emits an updated value each time its key is set. Use this to monitor changes to a key/value
145154
* in the store.

0 commit comments

Comments
 (0)