I find IndexedDB cumbersome and want to wrap the functionality with rxjs observables. I've come up with an angular2 service that seems to fit the bill, but I'm wondering if I'm using the observables correctly or if there might be any subscriptions I'm missing (plnkr):
Usage:
this.localDbService.set('storeName', key, value)
.subscribe(
x => console.log('stored key ', x),
err => console.error('error storing value', err)
);
this.localDbService.get('storeName', key)
.subscribe(
x => console.log('got value', x),
err => console.error('error getting value', err)
);
The service opens the database in the constructor and provides it using a ReplaySubject
. This is the first thing I think might have a better solution. I want some sort of observable that will provide me with a single value but only after initialization has finished, and provide the same value any time it is called. I use a ReplaySubject(1)
and use .take(1)
on it, so any subscribers will not get a value until one is provided, and will only get a single value and won't have to unsubscribe. Should I perhaps use an AsyncSubject
?
Also I'm catching errors in storing and querying and passing any errors from db creation up to the caller, am I missing anything here?:
store(storeName: string, key: any, value: any): Observable<any> {
return Observable.create((observer: Observer<any>) => {
try {
this.db.take(1).subscribe(db => {
if (!db) {
observer.error("IndexDB not supported!");
return;
}
var txn = db.transaction([storeName], "readwrite");
var store = txn.objectStore(storeName);
var req = store.add(value, key);
req.onerror = function(err) {
observer.error(err);
return;
};
req.onsuccess = function(e: any) {
observer.next(e.target.result);
observer.complete();
};
});
} catch(err) {
observer.error(err);
}
});
}