Home > Software engineering >  Need help parsing this type of json in Android using retrofit for API response handling
Need help parsing this type of json in Android using retrofit for API response handling

Time:06-17

Please show me a way to make a proper model for this JSON so that I get "Indian Premier League" as the key and the array next to it as value. We can have multiple leagues as well in the json.

{
    "keySeriesNews": {
        "Indian Premier League": [
            {
                "id": 203,
                "slug": "tata-ipl-2022-why-delhi-capitals-bought-shardul-thakur-for-inr-1075-crore",
                "competition_id": 3269,
                "image_id": 1203,
                "image_caption": "Shardul Thakur in action",
                "start_date": "2022-03-05 17:25:38",
                "created_at": "2022-03-05 12:08:19",
                "updated_at": "2022-04-15 06:50:30",
                "headline": "TATA IPL 2022: Why Delhi Capitals bought Shardul Thakur for INR 10.75 crore",
                "sport_id": 15,
                "image": {
                    "id": 1203,
                    "file_name": "shardulthakur_new.webp",
                    "created_at": "2022-04-15 06:47:41",
                    "image_path": "https://stagingkisma.6lgx.com/storage/images/shardulthakur_new_320x320.webp"
                },
                "competition": {
                    "id": 3269,
                    "slug": "indian-premier-league-2",
                    "competition_name": "Indian Premier League"
                }
            }
        ]
    }
}

I have used this model to parse in retrofit but it is not fetching any data from the API. It is completely blank. No data in it.

data class HomeNewsParentModel(

    @SerializedName("keySeriesNews" ) var keySeriesNews: JSONObject? = JSONObject()

)

However, when I use this model, it fetches data and I can access it. But problem is that it is hardcoded. I mean, these models will not capture data if the league name changes in any case. Here are the models which captured data.

data class HomeNewsParentModel(

     @SerializedName("keySeriesNews" ) var keySeriesNews: KeySeriesNews? = KeySeriesNews()

)
data class KeySeriesNews (

  @SerializedName("Indian Premier League" ) var league : ArrayList<League> = arrayListOf()

)
data class League (

  @SerializedName("id"             ) var id            : Int?         = null,
  @SerializedName("slug"           ) var slug          : String?      = null,
  @SerializedName("competition_id" ) var competitionId : Int?         = null,
  @SerializedName("image_id"       ) var imageId       : Int?         = null,
  @SerializedName("image_caption"  ) var imageCaption  : String?      = null,
  @SerializedName("start_date"     ) var startDate     : String?      = null,
  @SerializedName("created_at"     ) var createdAt     : String?      = null,
  @SerializedName("updated_at"     ) var updatedAt     : String?      = null,
  @SerializedName("headline"       ) var headline      : String?      = null,
  @SerializedName("sport_id"       ) var sportId       : Int?         = null,
  @SerializedName("image"          ) var image         : Image?       = Image(),
  @SerializedName("competition"    ) var competition   : Competition? = Competition()

)

I have coded for a parser on the generic side to handle key-value type JSON like this but the JSON object was empty when I used the first approach of the data model. I need to make a generic parser to fetch league names as well as their data in key-value format since there can be multiple leagues that can come in this response as well.

PS: This is my parser which is getting empty JSON Object

private fun parseJSONData(data: JSONObject){

        try {
            val jsonObject = JSONObject(data)
            for (key in jsonObject.keys()) {
                Toast.makeText(
                    [email protected](),
                    "Key : "   key   " Value: "   jsonObject.optString(key),
                    Toast.LENGTH_SHORT
                ).show()
            }
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

Your help is much appreciated. Thanks.

CodePudding user response:

Just a tip - if you already have the JSON available, you can use this plugin to easily generate a first draft of your model and adapt it if needed.

Some questions:

  1. If you can have multiple leagues in your response, shouldn't keySeriesNews also be a list and not just a JSON object? For example like this:
{   
   "keySeriesNews": [       
      {             
        "id": 203,          
        "title": "Indian Premier League",
        "slug": "tata-ipl-2022-why-delhi-capitals-bought-shardul-thakur-for-inr-1075-crore",
        "competition_id": 3269,
        "image_id": 1203,           
        ...         
       }    
    ] 
}
  1. What's your reasoning for handling JSON manually instead of using a ConverterFactory?
  2. Where and how are you calling parseJsonData?

CodePudding user response:

Well, I am not sure about this is correct or not. If anyone has a standard way of doing it, it is much appreciated. However, I have used the JSONElement instead of JSONObject or JSONArray and have used Map to handle key-value type data in my model, and GSONConvertorFactory has got this one right and fetched data correctly. This is the model I used:

data class HomeNewsParentModel(

   @SerializedName("keySeriesNews" ) var keySeriesNews: HashMap<String, JsonElement>? = HashMap()

)

And I will parse JSONElement in my parseJsonData function to handle the key-value of this nonstandard JSON coming from API.

Hope this helped you in some way.

  • Related