Android Kotlin Retrofit, wait for response outside suspend

Viewed 1634

I've got into a situation where I need to call an endpoint, and wait for the response before continuing the flow

Sadly, I can't make the function 'suspend', since it will require a heavy refactor and I prefer to 'hack' it this once

I've tried waiting for event signal, waiting for a value, using RunBlocking with 'await()', non worked, and await never fires back (response is received when using .enqueue())

All I need is this to work, i don't mind the UI to freeze, the user to wait, or the code to be ugly. There is a 2 second timeout and its a sacrifice i'm willing to take

I'm not an android (or ios) developer, so i'll be glad to get any tips

Attaching my code:

API Interface

import com.google.gson.annotations.SerializedName
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.POST

interface ITaxForAddressApi {
    @POST("/myapi")
    fun getTaxForAddress(@Body body: TaxForAddressBodyRequest): Call<TaxRateEntity>
}

data class TaxForAddressBodyRequest(
    @SerializedName("address") val address: TaxForAddressBodyAddress
)

data class TaxForAddressBodyAddress(
    @SerializedName("streetAddress") val streetAddress: String,
    @SerializedName("city") val city: String,
    @SerializedName("state") val state: String,
    @SerializedName("zip") val zip: String,
    @SerializedName("country") val country: String
)

data class TaxRateEntity(@SerializedName("tax") val taxRate: Double)

Calling code:

val addressBody = 
    TaxForAddressBodyAddress(
        shippingAddress.street,
        shippingAddress.city,
        shippingAddress.state,
        shippingAddress.zipCode,
        shippingAddress.country
        )
val taxRequest = TaxForAddressBodyRequest(addressBody)


val taxApiRequest = taxForAddressApi.getTaxForAddress(taxRequest)
taxApiRequest.enqueue(SafeCallback(object : CallbackResponseListener<TaxRateEntity> {
            override fun onSuccess(response: TaxRateEntity) {
                'Do Something here'
            }

            override fun onFailure(t: Throwable) {
                'Alert'
            }
        }))
}

Attempt with runBlocking (with try-catch of course):

runBlocking {
    val tax = taxForAddressApi.getTaxForAddress(taxRequest).await()
}
1 Answers

Retrofit's Call has an execute() method that you can invoke if you're fine with blocking the calling thread and you need to get the response synchronously. Keep in mind that you might need to disable StrictMode which would throw a NetworkOnMainThreadException by default.

Related