'Rxjava polling with observable
I would need to do an API call every 1 second and keep retrying while the "status" is "in_progress". However, every time I do the API call, I would receive a new QR code which I'd need to show in the UI. The call stops when "status" becomes "successful"
The response data class is
data class PollingData(
val status: Status,
val qrCode: String?,
)
I have this code in my repository which takes care of the 1-sec call
override fun poll(id: String): Observable<PollingData> {
return api.poll(id)
.subscribeOn(schedulerProvider.io())
.flatMap {
return@flatMap when (response.status) {
"successful" -> Observable.just(it)
"failed" -> Observable.error(VerificationFailedException())
"in_progres" -> Observable.error(NotReadyException())
}
}
.retryWhen {
it.flatMap { error ->
when (error) {
is NotReadyException -> Observable.just(Any()).delay(1, TimeUnit.SECONDS)
else -> Observable.error(error)
}
}
}
}
private class NotReadyException : Exception()
private class VerificationFailedException : Exception()
In my viewmodel I call the poll function
private fun pollForResponse(id: String) {
repository.poll(id)
.subscribeOn(schedulerProvider.io())
.observeOn(schedulerProvider.ui())
.subscribe(
{
when (response.status) {
"in_progress" -> response.qrCode?.let { _qrCodeLiveData.value = it } // update qr code ui
"successful" -> // done
"failed" -> // failed
}
},
{
// error
}
)
}
This does not work because in the repository, when the status is "in_progress" I throw NotReadyException which is handled by retryWhen. Therefore, the QR code never reaches the ViewModel to update the UI.
What is the correct way of doing this?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
