Kuba
Kuba

Reputation: 1455

Angular 2 http - combine multiple Observables

I'm totaly new in async Observable world. I hope somebody help me.

I have two Observable<boolean> and I want to combine them.

I tried to use:

var obs1 = Observable.of(true).delay(1000);
var obs2 = Observable.of(false).delay(100);    
obs1.combineLatest(obs2, (obs1Val, obs2Val) => {
    //bool result
    });

and thats almost it... almost because I want to start obs2 when obs1 is finished, with combineLatest both starts in the same time.

obs1 and obs2 here are simple examples in my case thats angular http requests:

obs1 : Observable<boolean> = http.get(...).map(d => <boolean>d);

Thanks in advance for help

Upvotes: 1

Views: 996

Answers (3)

kit
kit

Reputation: 4920

If you want to start obs2 when you get response from obs1, it has to be called in onNext of obs1.subscribe.

getBothResult() {
  return Rx.Observable.create(function (observer) {
    obs1 : Observable<boolean> = http.get(...).map(d => <boolean>d);
    obs1.subscribe((obs1Value) {
      Observable.of(false).delay(100).subscribe(obs2Value => {
        //compute value from obs1Value and obs2Value as they are visible in closure assign it to eg. finalValue
        var finalValue = obs1Value + obs2Value;
        observer.onNext(finalValue);
      });  
    });
  });
}    

It's very possible that an operator exists that does all those things in some nifty way, however I'm not aware of it.

Upvotes: 1

Skippy
Skippy

Reputation: 346

As you want to have obs2 execute after obs1, we can wait for a response In the Rx world, you should avoid subscribing to an observable, and then subscribing to another observable in the callback.

Here is an approach that should get you the result you are looking for.

var obs1 = Observable.of(true).delay(1000);
var obs2 = Observable.of(false).delay(100);
var obsOf1And2 = obs1.flatMap(obs1Response => 
    obs1Response.flatMap(obs2Response => { 
        // do what you want with both responses 
    }));

obsOf1And2.subscribe(console.log);

Upvotes: 0

igorzg
igorzg

Reputation: 1506

You can use observable zip

 let obs1 = Observable.of(true).delay(1000);
 let obs2 = Observable.of(false).delay(100);    

 let source = Observable.zip(
      obs1,
      obs2,
      (ob1, ob2) => {
        return {
          value1: ob1,
          value2: ob2
        };
      }
  );
  source.subscribe(data => console.log(data))

Upvotes: 1

Related Questions