Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to resolve multiple Observables

I have 2 (or more) Observables returned from services, each of them only returning one value (think Observable.just()). Each of them is of different type (I'm writing in TypeScript so types matter).

Is there a way to know when all Observables resolved (using promises terminology) either successfully or failed, I need to be able to handle failures individually, and carry on.

contrived example:

const obs1  = someService.getThisThing(); //Observable<Type1>
const obs2  = someService.getAnotherThing(); //Observable<Type2>

const someObj = {};

obs1.subscribe(v1 => someObj.v1 = v1);
obs2.subscribe(v2 => someObj.v2 = v2);

// call someFunc(someObj), only when both above observables resolved to a value
someFunc(someObj);

I have tried using merge but then I loose type safety as values may come in any order, and I have to inspect their type in .subscribe to determine which is which

I have tried combine and combineLatest as described here - but then they both resolve at the same time, and if 1 fails - everything fails

like image 927
dark_ruby Avatar asked Mar 11 '23 02:03

dark_ruby


1 Answers

If you need to be able to handle each error individually then you'll have to append catch() (or maybe some other operator) to each Observable. Operators such as forkJoin() or merge() always send error notification when any of their sources send an error.

const Observable = Rx.Observable;

let sources = [
  Observable.of(123).catch((err) => Observable.of('caught error')),
  Observable.throw('error').catch((err) => Observable.of('caught error'))
];

Observable.forkJoin(...sources)
  .subscribe(values => console.log(values));

See live demo: https://jsbin.com/hirodef/3/edit?js,console

The second Observable throws an error that is caught with catch() and replaced with caught error string.

This demo prints to console:

[123, "caught error"]
like image 50
martin Avatar answered Mar 23 '23 22:03

martin