Reputation: 62024
In my app I use rxjs and I have a method that looks like this:
query<T extends TableRow>(queryString: string, silent = false): Observable<T[]> {
return this.sqliteService.dbQuery<T>(queryString).pipe(
tap(val => {
if (this.configService.debugMode && !silent) {
console.log(`\n${queryString}`);
console.log(val);
}
})
);
}
My query
method interlly calls dbQuery
that queries an sqlite database.
Also, the query
method is called many times in my app. So I'd like to globally cache the result whenever the queryString
is the same.
In other words, I'd like the query
method to avoid calling again dbQuery
when called with a queryString
parameter that has been called before, by returning the previously-cached value.
Not sure if this is relevant: my query
method lives in an Angular singleton service.
Upvotes: 1
Views: 2439
Reputation: 62024
I ended up with the following solution:
private cache: Observable<string>[] = [];
getItem(id: number): Observable<string> {
if (!this.cache[id]) {
this.cache[id] = this.query<string>(
`SELECT column FROM table WHERE id = ${id}`
).pipe(shareReplay());
}
return this.cache[id];
}
Upvotes: 1
Reputation: 13515
First time through, save the remote value to a local cache property with a key that is the query string.
On subsequent requests, return the existing property for the corresponding key.
private cache = {};
query<T extends TableRow>(queryString: string, silent = false): Observable<T[]> {
if (this.cache.hasOwnProperty(queryString)) {
return of(this.cache[queryString]);
}
return this.sqliteService.dbQuery<T>(queryString).pipe(
tap(val => {
this.cache[queryString] = val;
if (this.configService.debugMode && !silent) {
console.log(`\n${queryString}`);
console.log(val);
}
})
);
}
Upvotes: 3