Correct way to parse eterogeneous arrays of data - android

I have this model that I would like to parse from JSON:
class CFInsertedValuesStructure {
#SerializedName("id")
val id : Int? = null
#SerializedName("value")
val value : List<String> = listOf();
#SerializedName("field_id")
val field_id : String? = null
}
There is a problem with the parameter "value" because it isn't always an array of String, sometimes it could be just a String type.
So when happens I would like to recognise it and create an array of just one String.

depending on what library you use the json parsing it may require a custom parsing type e.g. for kotlinx.serialization you might need to do something like a custom serializer
https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serializers.md#specifying-serializer-on-a-property
better still : tell you server-side developer it should always be an array!

Related

Android: How to parse nested json array with different data type objects using retrofit - moshi?

I want to parse nested json using retrofit moshi. The json data i'm having is an array, inside array first element is string & second is again an array.
I don't want to parse first element in the array ("list"), just want to parse second element from the array (i.e. Inner array).
But i'm facing challenges exactly here with the data object to be use.
Obviously we can use Any type in kotlin with list, but again will loose type of the object inside the list.
Json Format:
{
"results": [
"list",
[
{
//jsonobj
},
{
//jsonobj
}
]
]
}
I want to parse json with this Data class that i have created without parsing first element & parse directly second element.
#JsonClass(generateAdapter = true)
data class ResponseModel(
#Json(name = "results")
val results: List<Results?>?,
) {
#JsonClass(generateAdapter = true)
data class Results(
#Json(name = "reference")
val reference: String?,
#Json(name = "enabled")
val enabled: Boolean,
)
}
fromJson overridden function
#Throws(IOException::class)
override fun fromJson(reader: JsonReader): C {
val result = newCollection()
reader.beginArray()
while (reader.hasNext()) {
result?.add(elementAdapter.fromJson(reader)!!)
}
reader.endArray()
return result
}
This is throwing an exception saying EXPECTED_OBJECT but it was STRING when trying to parse first element ("list").
i'm stuck here & not able to proceed further.
So can somebody plz help me to get out from here? any help will be appreciated.

Multi type object in kotlin

from an API call i get as response a body with this structure
open class BaseResponseEntity {
#SerializedName("result")
val result: ResultEnum = ResultEnum.NONE
#SerializedName("errorCode")
val errorCode: String = ""
#SerializedName("errorMessage")
val errorMessage: String = ""
#SerializedName("successMessage")
val successMessage: String = ""
#SerializedName("value")
val code: LastPaymentCodeModel?
}
where the field "value" can be three types: null, String or LastPaymentCodeModel. How can i get this?
I managed to put a ? so that both null and LastPaymentCodeModel are handled, but i don't know how to handle the String type too.
I think the best approach would probably be to use type Any? for code.
Then you should write a custom GSon serializer/deserilizer (JsonDeserializer<BaseResponseEntity>) for the BaseResponseEntity object.
In this Json deserializer, you would need to check the type of value (e.g is it a string or a data structure) and decode it to the correct object type.
Alternative, to avoid the use of Any?, you could leave the model exactly as you have it. You will still need to write a custom JsonDeserializer, however if value is a string then it would still create a LastPaymentCodeModel, using the string value as one of it's properties.

How to manage null value for android application while JSON parsing via GSON lib in kotlin

I am working on android application and want to manage null value that is comes from API.
I did not found the best solution.
I also try these methods
1. While generating getter in model class i give a conditional statement in getter like
if(value == null){
value = ""
}
but this is not a right way because of i have to write this code for each and every getter in whole application.
2. replace the string from 'null' to "" before JSON parsing.
this is replace all type of value (int/float etc) in to blank string that is invalid.
You can use JsonDeserializer to create your Gson.
You can create model class like this
class ExampleModel {
#SerializedName("id")
#Expose
val id: Int? = null
#SerializedName("category")
#Expose
val category: String? = null
}
This class will be able to handle null value and data as well.

How can I deserialize this?

I have a JSON response of an API REST call that I am not pretty sure how should I deserialize...
{
.....
"date": "10-10-19",
"rates": {
"GBP" : 101.01,
"EUR" : 102.01,
"AUD" : 103.4,
......
}
}
I would like to know How could I deserialize the "rates" object?. I think it was a Map object so using Gson I make the next POJO:
class POJO(
private val base: String,
private val date: Date,
private val rates: Rate
)
And my Rate class is
class Rate ( private val currency : Map <String, Double> )
It doesn't make any problem unless I try to use this Map in my class. When I try to access to this variable for example here :
view?.converterBinder!!.setCurrencyList(it.data!!.rates.currency)
currency is null because I think Gson doesn't know how to resolve it. I don't know if I had to deserialize it manually or there are any solution for this using Gson.
Any thoughts??
The provided Json is completely wrong, this is how it should be formatted
{
"date": "10-10-19",
"rates": {
"GBP": 101.01,
"EUR": 102.01
}
}
Please check with https://jsonlint.com to confirm the validity of a Json.
So you have a json object with a String "date", then you have another json object called "rates" containing 2 numeric Doubles "GBP" and "EUR".
Each Json should be represented by a class, so to parse it create the following object containing the 2 classes
object Models {
data class Rates(#SerializedName("GBP") val gbp: Double,
#SerializedName("EUR") val eur: Double)
data class ExchangeRates(#SerializedName("date") val date: String,
#SerializedName("rates") val rates: Rates)
}
Now you pass the class ExchangeRates to Gson to deserialize your object and you should have all the data in place.

retrofit generate unformatted complex json object

I am having a very strange problem
I am trying to build a complex json object which contains nested json
I have created it but when I send the request it crash
here is the format that I need
{"JR":"{"Text":"","userID":4,"Context":"","ClinicId":1}","TO":"getWatsonMessage","ver":2}
what I found in the request body as following:
{"JR":"{\"Text\":\"\",\"userID\":4,\"Context\":\"\",\"ClinicId\":1}","TO":"getWatsonMessage","ver":2}
which make the app crash
here is my code
data class MyBody #JvmOverloads constructor(
#SerializedName("ver") val version: Int,
#SerializedName("TO") val methodName: String,
#SerializedName("JR") val jsonParams: String,
#SerializedName("Method") var methodType: String? = null
)
and this is how I create the sub json object
val jsonJR = JSONObject()
jsonJR.put("Text",text)
jsonJR.put("userID",userId)
jsonJR.put("Context",context)
jsonJR.put("ClinicId",clinicId)
can anyone please help ?
It seems like the problem is with your JR of type String.
All the other params are in the proper format right?
So, I suggest that you provide type JR to another custom data class like
data class JRDataClass{
Text : String,
//and the rest of the data types
}

Categories

Resources