lvm12
lvm12

Reputation: 53

getting unexpected json token at offset 0 with kotlin.serialization

Trying to parse json string from here, however kotlin serialization is throwing this error:kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 0: Expected beginning of the string, but got { at path: $JSON input: {"events":[{"id":1

The json string is fetched with retro fit using this function:

@GET("bootstrap-static")
suspend fun getBootstrapJson(): String

and is then converted with this function in a custom json converter object:

fun convert(string: String): BootStrapModel{
    return Json{ignoreUnknownKeys = true}.decodeFromString(string)
}

The boot strap model is defined like this:

@Serializable
data class BootStrapModel(
    @SerialName("events") val events: List<Events>,
    @SerialName("game_settings") val gameSettings: GameSettings,
    val phases: List<Phases>,
    val teams: List<Team>,
    @SerialName("total_players") val totalPlayers: Int,
    val players: List<Player>,
    @SerialName("element_stats") val elementStats: List<ElementStats>,
    @SerialName("element_types") val elementTypes: List<ElementTypes>,
)

All custom data types here are serializable data classes with and data that I want. any help is appreciated.

Upvotes: 4

Views: 9474

Answers (1)

Kewi
Kewi

Reputation: 127

I believe this is happening because you are requesting a string result from your @GET suspend function call - getBootstrapJson(): String. The error is telling you that a string is the expected response type as per your request, but it is actually returning a JSON object. The JSON you are receiving shows that it is an object (the curly bracket '{'), you then have an array of objects titled events:

{
    "events": [
        {
            "id": 1 

Therefore, instead of requesting a string in your Retrofit suspend function, you should request an object which contains a list of event(s) e.g.

suspend fun getBootstrapJson(): BootStrapModel

Alternatively you could use a GSON converter -

implementation("com.google.code.gson:gson:2.10.1")
...

 private val retrofit: Retrofit = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        ...

Example model:

   data class BootStrapModel(
        @SerializedName("events") 
        val events: List<Event> // Request for a list of Event objects
        ...
    )

    data class Event(
        @SerializedName("id")
        val id: Long,
        @SerializedName("name")
        ...
    )

    data class ChipPlay (
        @SerializedName("chip_name")
        val chipName: ChipName,
        @SerializedName("num_played")
        val numPlayed: Long
    )
        ...

There are websites such as https://app.quicktype.io/ where you can drop a copy of the JSON and it will produce the Kotlin classes required. You can also download a plugin to Android studio so that the classes are created inside your program file: https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-

Upvotes: 0

Related Questions