0

I am working on a requirement, where as when making a service call to the API, if it is success, the response object will be a set of key-value in the following format:

string : {string: string}

For instance, the json response will be something similar like this:

{
    "contentName": "mobile",
    "language": "nz-en",    
    "content": {
        "data_pack_description_0": {"text": "Data only"},
        "data_pack25_description_0": {"text": "Pack 25"}
        "buying_title_0": {"text": "Buy an item"}
        "buying_description_0": {"text": "This is an item for sale"}
    }
}

I am planning to use Gson Serialize in the data model class, something similar like:

data class ResponseObject(
    @SerializedName("contentName")
    val contentName: String
    @SerializedName("language")
    val language: String
    @SerializedName("content")
    val content: Content
)

data class Content(
    //What should it be here so that we can use @SerializedName???
)

However, the problem is that, the key in the json string is dynamic, means that we don't know exactly what it is. That's why @SerializedName doesn't work cause we don't have the name.

How can I serialise the above json string into a Model so that it can be used in the ViewModel layer (the app I am working on is MVVM Kotlin)?

In fact, the question will be what's the best way to serialise information inside "content", knowing that we will not know exactly what will be return but we know the format:

"string": {"string" : "string"}

Thanks.

Long Dao
  • 1,341
  • 4
  • 15
  • 33

1 Answers1

0

Try: https://github.com/Kotlin/kotlinx.serialization

Write JSON definitions:

@Serializable
data class ResponseObject(
    val contentName: String,
    val language: String,
    // treat content as a map, so we can access it with dynamic keys
    val content: Map<String, Text>,
)

@Serializable
data class Text(
    val text: String,
)

Deserialize:

val json = """
{
    "contentName": "mobile",
    "language": "nz-en",
    "content": {
        "data_pack_description_0": {"text": "Data only"},
        "data_pack25_description_0": {"text": "Pack 25"},
        "buying_title_0": {"text": "Buy an item"},
        "buying_description_0": {"text": "This is an item for sale"}
    }
}
"""

println(Json.decodeFromString<ResponseObject>(json))

Output (re-formatted for readability):

ResponseObject(
  contentName = mobile,
  language    = nz-en,
  content     = {
    data_pack_description_0=Text(text=Data only),
    data_pack25_description_0=Text(text=Pack 25),
    buying_title_0=Text(text=Buy an item),
    buying_description_0=Text(text=This is an item for sale)
  }
)
Calarpo
  • 1
  • 1
  • 1
  • Any chance to make it work with the Gson @SerializedName? Reason being that I don't want to introduce another library to the app. Thanks. – Long Dao Jul 11 '23 at 21:53
  • @LongDao It's hard, Gson has poor Kotlin support, and no longer implements new features. I strongly recommend using kotlinx.serialization for new Kotlin projects. But you can see this if you want to try: https://stackoverflow.com/questions/2779251/ – Calarpo Jul 12 '23 at 15:35
  • hi @Calarpo, I tried following the article you sent but not quite understand. I am keen to get it work with GSON but unsure at this stage. Cause The API call I made looks like this: suspend fun getContents(): Result, so if there is a response coming back, it will be serialised immediately to ResponseObject. That's setup in the Repository class. – Long Dao Jul 13 '23 at 09:42