In My repository, I have two API calls that should be done sequentially.
- First API call returns Completable -> If this API call fails, we should not proceed further, if it succeeds we should continue with the second API call
- Second API call returns Single -> If this API call fails, we should NOT throw an error and we can still continue
How can I achieve this?
What I am doing now is using separate calls from repo.
Repository:
override fun activate(id: String): Completable {
return api1.post(Body(id = id))
.subscribeOn(schedulerProvider.io())
}
override fun fetchAd(id: String): Single<SummaryAd> {
return api2.getAd(adId)
.subscribeOn(schedulerProvider.io())
.map { it.toSummaryAd() }
}
ViewModel:
private fun activate(id: String) {
repository.activate(id)
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.subscribe(
{ // if it is successful, let's continue
fetchAd(id)
},
{ // otherwise fail
_state.value = State.ErrorActivation
}
).also { compositeDisposable.add(it) }
}
private fun fetchAd(id: String) {
repo.fetchAd(id)
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.subscribe(
{ // success
_state.value = State.ActivationSuccess(it)
},
{
// even though the call has failed, the activation is succeeded, so we still can proceed but with empty data
_state.value = State.ActivationSuccess(SummaryAd())
}
).also { compositeDisposable.add(it) }
}
Basically what I want ultimately is to have a single function in my viewModel and let the repository sequentially call them and only throw error If the first API call failed.
CodePudding user response:
Use andThen
activate(id)
.andThen(
fetchAd(id)
.onErrorReturnItem(SummaryAd())
)
CodePudding user response:
This is roughly what you need, depending on your implementation of _state you might also not need to set its value on UI thread.
compositeDisposable.add(
repository.activate(id)
.subscribeOn(schedulerProvider.io())
.andThen{
repo.fetchAd(id)
.subscribeOn(Schedulers.io())
.onErrorReturnItem { SummaryAd() }
}
.observeOn(schedulerProvider.ui())
.subscribe(
{
_state.value = State.ActivationSuccess(it)
},
{
// this will be executed only, in case of activate request failure, as fetch add can never fail due to one rrorReturn
_state.value = State.ErrorActivation
}
)
)