Handle exception of single object in mapping of Json Array to POJO Array using Gson in Android-ThrowExceptions

Exception or error:

I’m reading Json array from third-party API and mapping it directly to POJO array using Gson. Frequently, I’m getting missing data for some of objects and all missing parameters have "N/A" value.

My POJO class mixed of String and Double variables, now when "N/A" is returned where Double value is expected, the app get crashed. Definitely, I can loop through them manually and skip objects with missing data, but I’m looking for alternative solution that help me to do same in mapping using Gson.

POJO class (Kotlin syntax)

class StockData(
    var symbol: String?,
    var name: String?,
    var currency: String?,
    var price: Double,
    @SerializedName("day_change")
    var dayChange: Double,
    @SerializedName("change_pct")
    var changePct: Double,
    var price90DayHigh: Double,
    var price90DayLow: Double
)

Mapping

val stockDataList = Gson().fromJson(response.body()!!.asJsonObject.get("data"),
                    Array<StockData>::class.java).toList()

Json with available data

{
    "symbol": "AAK.ST",
    "name": "AAK AB (publ)",
    "currency": "SEK",
    "price": "189.15",
    "price_open": "190.90",
    "day_high": "190.95",
    "day_low": "188.30",
    "52_week_high": "203.80",
    "52_week_low": "131.62",
    "day_change": "-1.35",
    "change_pct": "-0.71",
    "close_yesterday": "190.50",
    "market_cap": "47993210000",
    "volume": "110641",
    "volume_avg": "476416",
    "shares": "253730934",
    "stock_exchange_long": "Stockholm Stock Exchange",
    "stock_exchange_short": "OMX",
    "timezone": "CET",
    "timezone_name": "Europe/Stockholm",
    "gmt_offset": "3600",
    "last_trade_time": "2020-02-21 17:29:54",
    "pe": "32.60",
    "eps": "5.32"
}

Json with missing data

{
    "symbol": "HEMF-PREF.ST",
    "name": "N/A",
    "currency": "N/A",
    "price": "0.00",
    "price_open": "N/A",
    "day_high": "N/A",
    "day_low": "N/A",
    "52_week_high": "N/A",
    "52_week_low": "N/A",
    "day_change": "N/A",
    "change_pct": "N/A",
    "close_yesterday": "N/A",
    "market_cap": "N/A",
    "volume": "N/A",
    "volume_avg": "N/A",
    "shares": "N/A",
    "stock_exchange_long": "Stockholm Stock Exchange",
    "stock_exchange_short": "OMX",
    "timezone": "CET",
    "timezone_name": "Europe/Stockholm",
    "gmt_offset": "3600",
    "last_trade_time": "N/A",
    "pe": "N/A",
    "eps": "N/A"
}
How to solve:

There can be 2 ways:
1.You create GsonAdapter adapter , like

class StockDataAdapter: TypeAdapter<StockData> {
   fun read(reader: JsonReader): StockData {
      ....handle actual json parsing here, setting default value to field if parsing failed
    }
}

and then

val gson =GsonBuilder().registerTypeAdapter(StockData.class,  StockDataAdapter()).create();
val stockDataList = gson.fromJson(response.body()!!.asJsonObject.get("data"),
                Array<StockData>::class.java).toList()
  1. You can make all fields String type and parse actual values in place, like

    class StockData(
    val symbol: String?,
    val name: String?,
    val currency: String?,
    val price: String,
    @SerializedName(“day_change”)
    val dayChange: String?,
    @SerializedName(“change_pct”)
    val changePct: String,
    val price90DayHigh: String,
    val price90DayLow: String
    ) {
    val priceAsDouble:Double
    get() = try {price.toDouble()}catch(e:Exception){0.0}
    }

Leave a Reply

Your email address will not be published. Required fields are marked *