Home > Blockchain >  Response body return null when there's actually a value
Response body return null when there's actually a value

Time:11-25

I expect the response body to return a value when the status code is not successful because when I try it on Postman it actually gave me a message or one of the attributes of the JSON Array. But, when I try to store the response body into a variable, it always returns null. I don't know why

Here's the ApiService

@POST("register")
    fun registerAkun(
        @Body registrasiAkun: RegistrasiBodyRequest
    ): Call<RegistrasiResponse>

Here's the method inside RemoteDataSource

override fun registrasiAkun(registrasiAkun: RegistrasiBodyRequest): LiveData<ApiResponse<RegistrasiResponse>> {
        val result = MutableLiveData<ApiResponse<RegistrasiResponse>>()
        result.postValue(ApiResponse.Loading)
        EspressoIdlingResource.increment()

        val client = apiService.registerAkun(registrasiAkun)
        client.enqueue(object : Callback<RegistrasiResponse> {
            override fun onResponse(
                call: Call<RegistrasiResponse>,
                response: Response<RegistrasiResponse>
            ) {
                val data = response.body()
                Log.d("RemoteDataSource0", "$data")

                if (response.isSuccessful) {
                    result.postValue(data?.let {
                        ApiResponse.Success(data)
                    })
                } else {
                    data?.let {
                        result.postValue(ApiResponse.Error(it.message.toString()))
                    } ?: run {
                        Log.d("RemoteDataSource", "$data dan $response")
                    }
                }
            }

            override fun onFailure(call: Call<RegistrasiResponse>, t: Throwable) {
                Log.d("RemoteDataSourceFailure", t.message.toString())
                result.postValue(ApiResponse.Error(t.message.toString()))
            }
        })

        return result
    }

Model:

data class RegistrasiResponse(

    @SerializedName("message")
    val message: String? = null,

    @SerializedName("customer")
    val customer: CustomerResponse? = null
)
data class CustomerResponse(
    @field:SerializedName("nama_customer")
    val namaCustomer: String?,

    @field:SerializedName("id_customer")
    val idCustomer: Int?,

    @field:SerializedName("email_customer")
    val emailCustomer: String?
)

And here's the Log

I/okhttp.OkHttpClient: --> POST MY_URL
I/okhttp.OkHttpClient: Content-Type: application/json; charset=UTF-8
I/okhttp.OkHttpClient: Content-Length: 84
I/okhttp.OkHttpClient: {"email_customer":"[email protected]","nama_customer":"tesdlu","password":"12345678"}
I/okhttp.OkHttpClient: --> END POST (84-byte body)
I/okhttp.OkHttpClient: <-- 409 MY_URL (287ms)
I/okhttp.OkHttpClient: x-powered-by: PHP/7.4.25
I/okhttp.OkHttpClient: cache-control: no-cache, private
I/okhttp.OkHttpClient: content-type: application/json
I/okhttp.OkHttpClient: vary: Accept-Encoding
I/okhttp.OkHttpClient: date: Thu, 25 Nov 2021 06:26:48 GMT
I/okhttp.OkHttpClient: server: LiteSpeed
I/okhttp.OkHttpClient: alt-svc: quic=":443"; ma=2592000; v="43,46", h3-Q043=":443"; ma=2592000, h3-Q046=":443"; ma=2592000, h3-Q050=":443"; ma=2592000, h3-25=":443"; ma=2592000, h3-27=":443"; ma=2592000
I/okhttp.OkHttpClient: {"message":"User Registration Failed!"}
I/okhttp.OkHttpClient: <-- END HTTP (39-byte body)
D/RemoteDataSource0: null
D/RemoteDataSource: null dan Response{protocol=h2, code=409, message=, url=MY_URL}

And here's what I expect or these

Whenever the response is successful, it returns this

RegistrasiResponse(message=Registrasi Sukses, customer=CustomerResponse(namaCustomer=aaaaaa, idCustomer=50, emailCustomer=aaaaa@mail.com))

Postman response success

CodePudding user response:

You should obtain the body from errorBody() instead of body() for case !isSuccessful.

EDIT:
You may need an object to hold the message. e.g.

data class ErrorResponse(
    val message: String? = null
)

and inside onResponse() will looks like this

if (response.isSuccessful) {
    result.postValue(response.body()?.let { 
        ApiResponse.Success(it)
    })
} else {
    response.errorBody()?.string()?.let {
        val error = Gson().fromJson(it, ErrorResponse::class.java)
        result.postValue(ApiResponse.Error(error.message.orEmpty()))
    } ?: run {
        Log.d("RemoteDataSource", "${response.errorBody()?.string()} dan $response")
    }
}

CodePudding user response:

Finally found the solution to get the message string by converting it

response.errorBody()?.let { errorBody ->
                        try {
                            val jsonObject = JSONObject(errorBody.string())
                            val error = jsonObject.getString("message")
                            result.postValue(ApiResponse.Error(error))
                        } catch (e: Exception) {
                            result.postValue(ApiResponse.Error("${e.message}"))
                        }
                    }
                
  • Related