Axbor Axrorov
Axbor Axrorov

Reputation: 2806

Cancel retrofit request when using it with coroutine flow

I have retrofit interface like below:

@GET("products")
fun getProducts(
    @Query("limit") limit: Int,
    @Query("offset") offset: Int
): Flow<List<Product>>

I'm calling this method like below:

restService
    .getProducts(limit, offset)
    .flowOn(ioContext)
    .catch { /* handle error */ }
    .collect { /* handle result */ }

This code snippet could be called in situations:

  1. When pulled Swipe refresh
  2. When loading the next portion of data. That's why I want to cancel the previous request before making a new one. How I can achieve this?

Upvotes: 0

Views: 1089

Answers (1)

niqueco
niqueco

Reputation: 2408

I think your best option is to run the collection in a coroutine that gets cancelled when the data is not needed anymore. It can be as part of a flow. An example:

combineTransform(limitFlow, offsetFlow, refreshSignal) {
    emitAll(restService.getProducts(limit, offset))
}.collect { }

(here refreshSignal would emit whenever a refresh is needed).

The flow returned by getProducts() will be cancelled each time new values are emitted from the input flows.

You could as well cancel the collection manually, keeping the job and calling cancel on it.

val getProductsJob = launch {
    restService
        .getProducts(limit, offset)
        .flowOn(ioContext)
        .catch { /* handle error */ }
        .collect { /* handle result */ }
}

... then you can cancel that job whenever you feel like:

getProductsJob.cancel()

Upvotes: 1

Related Questions