0

An API that I use returns data in the format:

{"status":1,
 "message": "some_response_message"
 "data": [{object},{object}...]
}

Depending on the specific endpoint, the {object} is different.

I am trying to create a generic deserializer to handle the responses, and am using this as my starting point: Get nested JSON object with GSON using retrofit

(At the moment I'm just trying to get the first call working with a generic deserializer so I can add more calls later on)

Here is my deserializer:

class MyDeserializer<T> : JsonDeserializer<T>{
    override fun deserialize(
        json: JsonElement?,
        typeOfT: Type?,
        context: JsonDeserializationContext?
    ): T {
       val data : JsonElement? = json?.asJsonObject?.get("data")
        return  Gson().fromJson(data, typeOfT)
    }
}

However, I'm getting an error thrown when I try to use this: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

If I set a breakpoint on the val data... line, it never gets hit, so it seems like it's failing before it gets to using the custom deserializer.

Here's how I'm using the deserializer:

@Singleton
class RetrofitCSNetwork @Inject constructor(
) : CSNetworkDataSource {

    val gson: Gson = GsonBuilder()
        .registerTypeAdapter(weatherResponse::class.java, MyDeserializer<weatherResponse>())
        .create()


    private val networkApi = Retrofit.Builder()
        .baseUrl(CSBaseUrl)
        .client(
            OkHttpClient.Builder()
                .addInterceptor(
                    // TODO: Decide logging logic
                    HttpLoggingInterceptor().apply {
                        setLevel(HttpLoggingInterceptor.Level.BODY)
                    }
                )
                .addInterceptor(AuthInterceptor())
                .build()
        )
        .addConverterFactory(GsonConverterFactory.create(gson))
        .build()
        .create(RetrofitCSNetworkApi::class.java)

    override suspend fun getWeathers(request: GetWeatherRequest) =

        networkApi.getWeathers(request)
}

My data classes:

data class weatherResponse(
    @SerializedName("id") val id: Int?,
    @SerializedName("city_name") val city_name: String?,
    @SerializedName("image") val image: String?,
    @SerializedName("daily_weather_forecasts") val forecasts: List<dailyWeatherForecasts>,
    )

data class dailyWeatherForecasts(
    @SerializedName("city_id") val city_id: Int?,
    @SerializedName("valid_date") val valid_date: Int?,
    @SerializedName("snow") val snow: Double?,
    @SerializedName("max_temp") val max_temp: Double?,
    )

The interface:

interface CSNetworkDataSource {
    suspend fun getWeathers(request: GetWeatherRequest): Response<List<weatherResponse>>

}

Calling the function in the repo:

  private val network: CSNetworkDataSource = RetrofitCSNetwork()
    suspend fun getWeathers() {
        val testResponse  =network.getWeathers( GetWeatherRequest(null,"Colorado"))
   
    }

Any help greatly appreciated

Charlie Walker
  • 129
  • 1
  • 2
  • 9

0 Answers0