Reputation: 711
I have a use case whenever generic error like internet lost or unknown error occurs in API call need to show error UI with retry button. when user press retry previously failed API should call and resume the user flow.
API interface before migrating coroutines method:
interface TodoService {
@POST("todo/create")
fun createTodo(@Body request: TodoRequest): Call<TodoResponse>
}
API client:
fun <T> fetch(call: Call<T>, completion: (result: NetworkBoundResource<T>) -> Unit) {
call.enqueue(object : Callback<T> {
override fun onFailure(call: Call<T>, t: Throwable) {
// I have the mechanism save call object and completion and show error UI
// when user press retry fetch(call.clone(), completion
}
override fun onResponse(call: Call<T>, response: Response<T>) {
}
})
}
This was not a problem before migrating retrofit interface to coroutines suspend methods. Because I can just clone the retrofit call object (call.clone())
and retry the API call as explained in the code comments.
API interface after migrating coroutines method:
interface TodoService {
@POST("todo/create")
suspend fun createTodo(@Body request: TodoRequest): TodoResponse
}
Now how can i achieve same feature without Call object?
Upvotes: 6
Views: 2992
Reputation: 166
You can handle the retry by saving the action outside of the Coroutine job e. g. adding a dispatch on a button.
Here is simple example, but not completed:
class ViewModel {
val context = CoroutineScope(Dispatchers.Main)
var dispatchRetry: (() -> Unit)? = null
fun createTodo(requestData: TodoRequest) {
context.launch() {
try {
todoService.createTodo(requestData)
} catch (t: Throwable) {
dispatchRetry = { todoService.createTodo(requestData) }
}
}
}
fun retry() {
dispatchRetry?.invoke()
}
}
Upvotes: 1
Reputation: 142
use repositories and view model to get response through live data using coroutines and then in your activity user observers to get date this is the best way to use coroutines also best practice for MVVM
Upvotes: 0