lannyf
lannyf

Reputation: 11035

kotlin how to share common retrofit response handler code

Having code to get from two different endpoints, but the response json have same scheme and the response handler code are same.

internal interface DataApi {
    @GET("/api/api_1")
    fun getData_1(@QueryMap params: Map<String, String>?): Call<DataMpdel>


    @GET("/api/api_2")
    fun getData_2(@QueryMap params: Map<String, String>?): Call<DataMpdel>
}

private lateinit var dataApi: DataApi

init {
    dataApi = createDataApi()
}

private fun createDataApi() : DataApi {
    val restAdapter = Retrofit.Builder()
            .baseUrl(baseUrl)
            .client(okHttpClient)
            .addConverterFactory(getGsonConverterFactory())
            .build()
    return restAdapter.create(DataApi::class.java)
}

It could use if/else to call the different endpoint, but that will duplicate the handler code.

Update: create the handler function and in both onResposne() just call that function.

Any suggestion to be better with shared handler code?

private fun fetchFirst(){

    if (!UseDataApi_1) {
        //
        dataApi. getData_1(getQueryParams()).enqueue(object : Callback<DataModel> {
            override fun onResponse(call: Call<DataModel>?, response: Response<DataModel>?) {

              // same handler code 
            }

            override fun onFailure(call: Call<DataModel>?, throwable: Throwable?) {

      // same error handler code 

            }
        })
    } else {
        //
        dataApi. getData_1(getQueryParams()).enqueue(object : Callback<DataModel> {
            override fun onResponse(call: Call<DataModel>?, response: Response<DataModel>?) {

              // same handler code 
            }

            override fun onFailure(call: Call<DataModel>?, throwable: Throwable?) {

      // same error handler code

            }
        }) 
    }
}

Upvotes: 1

Views: 364

Answers (1)

jt-gilkeson
jt-gilkeson

Reputation: 2721

If you want to minimize the duplicate code, create the callback as a class object and use it for both calls (something like this):

private val callback = object : Callback<DataModel> {
   override fun onResponse(call: Call<DataModel>?, response: Response<DataModel>?) {
       // handler code 
   }

   override fun onFailure(call: Call<DataModel>?, throwable: Throwable?) {
       // error handler code 
   }
}

private fun fetchFirst() {
    if (UseDataApi_1) {
        dataApi.getData_1(getQueryParams()).enqueue(callback)
    } else {
        dataApi.getData_2(getQueryParams()).enqueue(callback)
    }
}

Upvotes: 1

Related Questions