Rxjava polling with observable

Viewed 44

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?

0 Answers
Related