Search code examples
javarx-javarx-java2

rxjava - how to switch to previous stream but also do some work on main thread once first observable is ready?


I have two observables that both make network calls but they depend on each other:

val ob1 = Observable.just(myservice.getNewsArticles())

ob1.flatMap{ newsArticle -> myservice.getCelebrityNamesFromArticle(newsArticle.id)} 
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())

this is what i have so far, but the issue is when ob1 completes i need to immediately update the UI while ob2(thats gets celebrity names) is running. also at the end i need the chain to return ob1 (like a switchMap etc).... so it seems somehow i need to call onNext with a scheduler or something before invoking the flatMap right ?

ps.i noticed that flatMap has a biFunction mapper but i could not get it to work.


Solution

  • If you don't want the UI update to run concurrently with the second call, just use observeOn(mainThread()).doOnNext(article -> updateUI(article)).flatMap.

    If you want to update the UI and fire off the second call, flatMap onto a merge of the UI update and the network call:

    obs.flatMap(article -> Observable.merge(
        Observable.fromAction(() -> updateUI(article))
           .subscribeOn(mainThread()),
        myservice.getCelebrityNamesFromArticle(article.id)
           .subscribeOn(Schedulers.io())
    ))
    .observeOn(mainThread());
    

    To get both the article and the result of the second call, you can just map over it after the second call, for a pair, etc:

    obs.flatMap(article -> Observable.merge(
        Observable.fromAction(() -> updateUI(article))
           .subscribeOn(mainThread()),
        myservice.getCelebrityNamesFromArticle(article.id)
           .subscribeOn(Schedulers.io())
           .map(celebrityNames -> Pair(article, celebrityNames))
    ))
    .observeOn(mainThread());