Dyna Dyna - 20 days ago 9
Javascript Question

RxJS5: .combineLatest() with projection function?

I need a way to pipe values from an observable to two functions that each accept a value and each in turn returns an observable (emiting only a single value, then completing). I was hoping

.combineLatest()
would allow me to pass a projection function, but it doesn't.

Sample code (not working):

const ac = [1, 2, 3]; // only as example, I have complex types in my array not numbers

Observable.from(ac)
.combineLatest(
// processFn should get a number as argument and return Observable<number>
// does not work because .combineLatest does not accept two functions as arguments :(
n => processFn1(n),
n => processFn2(n)
)
.map(([result1, result2] => {
// result1, result2 should be flat numbers here, not Observables
})
);


Any idea on how to do that?

Answer

Your idea to use the combineLatest operator is correct but it's in the wrong place. If you need to flat out observables you should be using mergeMap. This is a JSBIN that does what you expect: http://jsbin.com/rutovot/4/edit?html,js,console

The code looks like this:

const ac = [1, 2, 3];

Rx.Observable.from(ac)
  // use mergeMap, it takes a function that accepts a value and
  // returns an observable. MergeMap will listen to this observable
  // under the hood and next the result of this observable down the
  // the chain
  .mergeMap(val => {
    // Here we return an observable that combines the result of the
    // call to both the functions
    return Rx.Observable.combineLatest(fake(val), fake2(val));
  })
  .subscribe(val => console.log(val));