javaandroidkotlinretrofit2kanji

retrofit E/API: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $


I can get data form retrofit form this https://kanjiapi.dev/#!/ data {"kanji":"蛍","grade":8,"stroke_count":11,"meanings":["lightning-bug","firefly"],"kun_readings":["ほたる"],"on_readings":["ケイ"],"name_readings":[],"jlpt":1,"unicode":"86cd","heisig_en":"lightning-bug"}

MainActivity :

        val apiService = KanjiService.getInstance()
    val call = apiService.getKanji()

    call.enqueue(object : Callback<List<Kanji>>{
        override fun onResponse(call: Call<List<Kanji>>, response: Response<List<Kanji>>) {
            Log.i("API",response.body().toString())
        }

        override fun onFailure(call: Call<List<Kanji>>, t: Throwable) {
            t.message?.let { Log.e("API", it) }
        }
    })

data class Kanji :

data class Kanji(
val kanji:String,
val grade:Int?=null,
val stroke_count:Int,
val meanings:List<String>,
val heisig_en:String?=null,
val kun_readings:List<String>,
val on_readings:List<String>,
val name_readings:List<String>,
val jlpt:Int?=null,
val unicode:String,)

Kanjiservice :

const val BASE_URL = "https://kanjiapi.dev/v1/"
interface KanjiService {
    @GET("kanji/蛍")
    fun getKanji(): Call<List<Kanji>>

companion object{
    fun getInstance():KanjiService{
        return Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(KanjiService::class.java)
    }
}
}

this is the warning : E/API: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $


Solution

  • Your callback is looking for list from API Response, as you used this; Callback<List<Kanji>.

    First Observe your API Response, It is {} JsonObject, and you casted it into List in your API Callback.

    So fix this in your API Call like this;

      call.enqueue(object : Callback<Kanji>{
            override fun onResponse(call: Call<Kanji>, response: Response<Kanji>) {
                Log.i("API",response.body().toString())
            }
    
            override fun onFailure(call: Call<Kanji>, t: Throwable) {
                t.message?.let { Log.e("API", it) }
            }
        })
    

    also modify your Interface;

    @GET("kanji/蛍")
    fun getKanji(): Call<Kanji>