In my web app's client code I have a class responsible for a bunch of websocket IO. This class has a global itemUpdatedObservable
that various parts of the UI can subscribe to to do little things. There is also a public function UpdateItem
which returns a promise-esq Observable. When the item is updated in response to the call to UpdateItem
I want both the returned observable and global observable to emit. The returned observable should also complete after emitting.
I have come up with this solution:
// Singleton
class API {
readonly itemUpdatedObservable: Observable<Item>;
private pendingItemUpdates: { [id: string]: Observer<Item> };
constructor() {
this.itemUpdatedObservable = new Observable(observer => {
socketio.on('itemUpdated', res => {
// do a bunch of validation on item
// ...
if (!res.error) {
observer.next(res.item);
} else {
observer.error(res.error);
}
let pendingObs = pendingItemUpdates[res.id]
if (pendingObs) {
if (!res.error) {
pendingObs.next(res.item);
} else {
pendingObs.error(res.error);
}
pendingObs.complete()
delete pendingItemUpdates[res.id];
}
})
});
this.pendingItemUpdates
}
public UpdateItem(item: Item): Observable<Item> {
const o = new Observable(observer => {
let id = uniqueId(); // Some helper somewhere.
this.pendingItemUpdates[id] = observer;
socketio.emit('updateitem', {item: item, id: id});
}).publish();
o.connect();
return o;
}
}
My question is if there is a cleaner, shorter way of doing this? I have something like 10+ observables in addition to itemUpdatedObservable
that all are events for different Object types. This code is messy and unwieldy especially when I am writing it 10x over. Is there a way to streamline the two observables such that I am only calling observable.next(...)
or observable.error(...)
once?
The above code blob is a simplification of my actual code, there is a lot more validation and context-specific values and parameters in reality.