ccd
ccd

Reputation: 6948

Get the result of retrofit async call

I tried to use retrofit to get the response data of web api, but the result of response data seems not sync as the same.

fun fetchData(): LiveData<String> {

    val auth = Credentials.basic(name, pass)
    val request: Call<JsonElement> = webApi.fetchData()
    val response: MutableLiveData<String> = MutableLiveData()

    request.enqueue(object : Callback<JsonElement> {

        override fun onFailure(call: Call<JsonElement>, t: Throwable) {
            Log.e(TAG, "Failed to fetch token", t)
        }

        override fun onResponse(call: Call<JsonElement>, response: Response<JsonElement>) {
            response.value = response.body()
            Log.d(TAG, "response: ${response.value}")  // I can get the result of response
        }
    })

    return response  // But the function return with the null
}

You might need handler.

Upvotes: 0

Views: 519

Answers (1)

Manuel Mato
Manuel Mato

Reputation: 779

The enqueue method doesn´t wait to the response so is normal the null result in your return response.

To solve this, you doesn´t need to return nothing, only put your livedata in the scope class and update the value:

class YourClass {
    private var responseMutableLiveData: MutableLiveData<String> = MutableLiveData()
    val responseLiveData: LiveData<String> 
      get() = responseMutableLiveData

    fun fetchData() {
      webApi.fetchData().enqueue(object : Callback<JsonElement> {

        override fun onFailure(call: Call<JsonElement>, t: Throwable) {
            Log.e(TAG, "Failed to fetch token", t)
        }

        override fun onResponse(call: Call<JsonElement>, response: Response<JsonElement>) {
            responseMutableLiveData.postValue(response.body())
            Log.d(TAG, "response: ${response.value}")  
        }
    })
   }
}

The livedata is observed and, when the value changes, then the other class reacts to it.

Upvotes: 1

Related Questions