Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combining two Observable<Void>s

I'm still a reactive newbie and I'm looking for help.

func doA() -> Observable<Void>
func doB() -> Observable<Void>

enum Result {
    case Success
    case BFailed
}

func doIt() -> Observable<Result> {

    // start both doA and doB. 
    // If both complete then emit .Success and complete
    // If doA completes, but doB errors emit .BFailed and complete
    // If both error then error

}

The above is what I think I want... The initial functions doA() and doB() wrap network calls so they will both emit one signal and then Complete (or Error without emitting any Next events.) If doA() completes but doB() errors, I want doIt() to emit .BFailed and then complete.

It feels like I should be using zip or combineLatest but I'm not sure how to know which sequence failed if I do that. I'm also pretty sure that catchError is part of the solution, but I'm not sure exactly where to put it.

--

As I'm thinking about it, I'm okay with the calls happening sequentially. That might even be better...

IE:

Start doA() 
    if it completes start doB() 
        if it completes emit .Success 
        else emit .BFailed.
    else forward the error.

Thanks for any help.

like image 373
Daniel T. Avatar asked Oct 31 '15 20:10

Daniel T.


People also ask

How do I combine two observables?

The RxJS merge() operator is a join operator that is used to turn multiple observables into a single observable. It creates an output Observable, which concurrently emits all values from every given input Observables.

How do I combine two observables Rxjava?

If you want to merge observables of different type you need to use Observable. zip : Observable<String> o1 = Observable.


1 Answers

I believe .flatMapLatest() is what you're looking for, chaining your observable requests.

doFirst()
.flatMapLatest({ [weak self] (firstResult) -> Observable<Result> in
  // Assuming this doesn't fail and returns result on main scheduler,
  // otherwise `catchError` and `observeOn(MainScheduler.instance)` can be used to correct this
  // ...
  // do something with result #1
  // ...
  return self?.doSecond()
}).subscribeNext { [weak self] (secondResult) -> Void in
  // ...
  // do something with result #2
  // ...
}.addDisposableTo(disposeBag)

And here is .flatMapLatest() doc in RxSwift.

Projects each element of an observable sequence into a new sequence of observable sequences and then transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. It is a combination of map + switchLatest operator.

like image 196
Son Nguyen Avatar answered Sep 28 '22 10:09

Son Nguyen