Reputation: 1024
My JSON Resoponse looks like-
{
"body": {
"count": 4,
"sender": "margarete20181570"
},
"inserted_at": "2020-05-07T05:48:14.465Z",
"type": 1
},
{
"body": "savanna19562530 hit the SOS button!",
"inserted_at": "2020-05-06T09:17:36.658Z",
"type": 2
}
And I am using the Data Class like below to parse the above JSON, what is wrong here!
data class Notification(val body: String, val inserted_at: String, val type: Int) {
constructor(
msgBody: MessageNotification,
inserted_at: String,
type: Int
) : this(msgBody.sender + "Sent you " + msgBody.count + "Messages", inserted_at, type)
}
But this dosent work it gives parsing error like - Expected String , got object
My Api call looks like-
@GET("notifications")
suspend fun getNotifications(
@HeaderMap headers: HashMap<String, String>
): Response<List<Notification>>
The main objective is how to remodel the code such that the Notification
model class' different constructor will be called on different cases such that it does not give such error expecting string, got object
or expecting object got string
How should I improve my code to parse the response?
Any help is appreciated!
Upvotes: 2
Views: 776
Reputation: 1345
Since you are deserializing the JSON manually, this can a be solution you can try
data class Body(val count: Int, val sender: String)
data class Notification(val body: Any, val insertedAt: String, val type: Int)
Now, Parsing the JSON response
val jsonResponse = JSONArray(/*JSON response string*/) // I am guessing this is an array
(0 until jsonResponse.length()).forEach {
val jsonObj = jsonResponse.getJSONObject(it)
val jsonBody = jsonObj.get("body")
if (jsonBody is String) {
// Body field is a String instance
val notification = Notification(
body = jsonBody.toString(),
insertedAt = jsonObj.getString("inserted_at"),
type = jsonObj.getInt("type")
)
// do something
} else {
// Body field is a object
val jsonBodyObj = jsonObj.getJSONObject("body")
val body = Body(
count = jsonBodyObj.getInt("count"),
sender = jsonBodyObj.getString("sender")
)
val notification = Notification(
body = body,
insertedAt = jsonObj.getString("inserted_at"),
type = jsonObj.getInt("type")
)
// do something
}
}
I hope this helps or atleast you get an idea how you approach to solve your problem. You can also check Gson
exclusion strategy.
Upvotes: 1
Reputation: 369
The body
field in your JSON is an object and should map to an object defined in your project. You could have a class header like the following for that purpose:
data class Body(val count: Int, val sender: String)
Your Notification
class header would then have a Body
field to capture that part of your JSON response like so:
data class Notification(val body: Body, val inserted_at: String, val type: Int)
I generally use Gson for deserialization of Retrofit responses. It works really well and is easy to customize. Let me know if something needs clarification.
Upvotes: 0