Ophir Bushinsky
Ophir Bushinsky

Reputation: 1429

How to switchmap - emitting an object containing both original and new observable?

I want to create an observable which first gets a value from an async function, then use that value to get another value asynchronously, and emit an object containing both values.

Something like:

function getValue1(){
    // asynchronously...
    return Observable.of(value1);
}

function getValue2UsingValue1(value1){
    // asynchronously...
    // value1 is needed to get value2...
    return Observable.of(value2);
}

getValue1()
    .switchMap(value1=> getValue2UsingValue1(value1))
    //...
    // I want to get an observable that emits an object containing value1 
    // and value2: {value1: value1, value2: value2}

Any help is appreciated.

Upvotes: 3

Views: 1145

Answers (1)

martin
martin

Reputation: 96939

I think you can make:

var value1Cached = getValue1().publishReplay(1);
value1Cached.connect();
var value2 = value1Cached.concatMap(value1 => getValue2UsingValue1(value1));

Observable.forkJoin(value1Cached, value2)
    .map(values => {
        return {'value1': values[0], 'value2': values[1]};
    })
    .subscribe(val => console.log(val));

I'm using publishReplay() operator to turn this Observable into a ConnectableObservable with ReplaySubject inside to support caching. I guess you don't want to call the getValue1() twice.

Then forkJoin() waits for both Observables to complete and emits their values in an array.

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

This prints to console:

[object Object] {
  value1: "value1",
  value2: "value2"
}

Upvotes: 1

Related Questions