How to exclude or skip a JSON field without using custom adapter in Moshi and Retrofit2? I wanted to handle this particular field since the API provider has a very terrible structure.
Example
{
"status":{
"message":"Success",
"status":200
},
"data":[
{
"somefield":{
"data":"foo"
},
"roi_by_year":{
"2020_usd_percent":301.45619677746635,
"2019_usd_percent":83.83497240467483,
"2018_usd_percent":-72.35180629416075,
"2017_usd_percent":1293.9968257264447,
"2016_usd_percent":122.23036668622065,
"2015_usd_percent":36.81278481514266,
"2014_usd_percent":-57.34726933565019,
"2013_usd_percent":5394.285470792129,
"2012_usd_percent":156.47080487351116,
"2011_usd_percent":1474.0066666666667
}
}
]
}
I will need to handle manually the roi_by_year since every year there could be a new property added and the key has decremental pattern, to be fair this should be restructured as an array which is the easiest but no they prefer anti-pattern approach.
I use plugin to generate a Moshi (Codegen) and using RxJava with Retrofit2.
This is how the Kotlin class would look like
@JsonClass(generateAdapter = true)
data class NewsItemModel(
@Json(name = "samplefield")
val sampleField: SampleField,
@Json(name = "roi_by_year")
val roiByYear: RoiByYear
)
@JsonClass(generateAdapter = true)
data class RoiByYear(
@Json(name = "2020_usd_percent")
val usdPercent: Double,
@Json(name = "2019_usd_percent")
val usdPercent: Double,
@Json(name = "2018_usd_percent")
val usdPercent: Double,
@Json(name = "2017_usd_percent")
val usdPercent: Double,
@Json(name = "2016_usd_percent")
val usdPercent: Double,
@Json(name = "2015_usd_percent")
val usdPercent: Double,
@Json(name = "2014_usd_percent")
val usdPercent: Double,
@Json(name = "2013_usd_percent")
val usdPercent: Double,
@Json(name = "2012_usd_percent")
val usdPercent: Double,
@Json(name = "2011_usd_percent")
val usdPercent: Double
)
My approach is to skip the RoiByYear and handle it myself by iterating through JSON names in order to be adaptable for upcoming new year without updating the code yearly. I was able to do this in Volley with Java like this
JSONObject roi = object.getJSONObject("roi_by_year");
JSONArray keys = roi.names();
List<Double> year_roi = new ArrayList<>();
if (keys != null)
for (int j = 0; j < keys.length(); j++) {
String key = keys.getString(j); // Here's the dynamic key
double val = optionalDouble(roi, key); // Here's value
year_roi.add(val);
}
Here I am instead using List and add each value, I should now use Pair as well so I could now store the key and value all together.
Now I have problems:
- How to skip a field/property from Moshi Codegen but continue to serialize the other.
- How to retrieve the
roi_by_yearfield from the Retrofit2 since the response data type class is based onNewsItemModel. - How to thank you for saving me