Home > Software engineering >  Parse an array into an object using GSON
Parse an array into an object using GSON

Time:10-31

In my application I am using GSON with a JSON from the NASA API.

My intention is to convert that JSON into a class.

Once that is done, I retrieve the data fine... but not all of it.

Here is an abbreviated example of the JSON:

{
    "links": {
      "next": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-08&end_date=2015-09-09&detailed=false&api_key=DEMO_KEY",
      "previous": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-06&end_date=2015-09-07&detailed=false&api_key=DEMO_KEY",
      "self": "http://api.nasa.gov/neo/rest/v1/feed?start_date=2015-09-07&end_date=2015-09-08&detailed=false&api_key=DEMO_KEY"
    },
    "element_count": 25,
    "near_earth_objects": {
      "objet_one": [
        {
          "links": {
            "self": "http://api.nasa.gov/neo/rest/v1/neo/2465633?api_key=DEMO_KEY"
          },
          "id": "2465633",
          "neo_reference_id": "2465633",
          "name": "465633 (2009 JR5)",
          "nasa_jpl_url": "http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=2465633",
          "absolute_magnitude_h": 20.36,
          "estimated_diameter": {
            "kilometers": {
              "estimated_diameter_min": 0.2251930467,
              "estimated_diameter_max": 0.5035469604
            },
            "meters": {
              "estimated_diameter_min": 225.1930466786,
              "estimated_diameter_max": 503.5469604336
            },
            "miles": {
              "estimated_diameter_min": 0.1399284286,
              "estimated_diameter_max": 0.3128894784
            },
            "feet": {
              "estimated_diameter_min": 738.8223552649,
              "estimated_diameter_max": 1652.0570096689
            }
          },
          "is_potentially_hazardous_asteroid": true,
          "close_approach_data": [
            {
              "close_approach_date": "2015-09-08",
              "close_approach_date_full": "2015-Sep-08 20:28",
              "epoch_date_close_approach": 1441744080000,
              "relative_velocity": {
                "kilometers_per_second": "18.1279547773",
                "kilometers_per_hour": "65260.6371983344",
                "miles_per_hour": "40550.4220413761"
              },
              "miss_distance": {
                "astronomical": "0.3027478814",
                "lunar": "117.7689258646",
                "kilometers": "45290438.204452618",
                "miles": "28142173.3303294084"
              },
              "orbiting_body": "Earth"
            }
          ],
          "is_sentry_object": false
        },
        {
          "links": {
            "self": "http://api.nasa.gov/neo/rest/v1/neo/3426410?api_key=DEMO_KEY"
          },
          "id": "3426410",
          "neo_reference_id": "3426410",
          "name": "(2008 QV11)",
          "nasa_jpl_url": "http://ssd.jpl.nasa.gov/sbdb.cgi?sstr=3426410",
          "absolute_magnitude_h": 21.34,
          "estimated_diameter": {
            "kilometers": {
              "estimated_diameter_min": 0.1434019235,
              "estimated_diameter_max": 0.320656449
            },
            "meters": {
              "estimated_diameter_min": 143.4019234645,
              "estimated_diameter_max": 320.6564489709
            },
            "miles": {
              "estimated_diameter_min": 0.0891057966,
              "estimated_diameter_max": 0.1992466184
            },
            "feet": {
              "estimated_diameter_min": 470.4787665793,
              "estimated_diameter_max": 1052.0225040417
            }
          },
          "is_potentially_hazardous_asteroid": false,
          "close_approach_data": [
            {
              "close_approach_date": "2015-09-08",
              "close_approach_date_full": "2015-Sep-08 14:31",
              "epoch_date_close_approach": 1441722660000,
              "relative_velocity": {
                "kilometers_per_second": "19.7498128142",
                "kilometers_per_hour": "71099.3261312856",
                "miles_per_hour": "44178.3562841869"
              },
              "miss_distance": {
                "astronomical": "0.2591250701",
                "lunar": "100.7996522689",
                "kilometers": "38764558.550560687",
                "miles": "24087179.7459520006"
              },
              "orbiting_body": "Earth"
            }
          ],
          "is_sentry_object": false
        }
      ]
  }
}

Well, I have a class called NasaResponse:

class NasaResponse(
    val element_count: Int,
    val neo: near_earth_objects,
    val links: links
)

class links(
    var next: String,
    val previous: String,
    val self: String
)

class near_earth_objects(
    val objeto_uno: ArrayList<NeoItem>,
)

I also have a class called NeoItem with the data I am interested in for each object in the JSON array "object_one".

data class NeoItem(
    val id: Int,
    val name: String,
    val absolute_magnitude_h: Double,
)

The JSON elements such as the "links" (next, previous or self) or the "element_count" can be retrieved without any problem from my activity.

 JsonToClass = gson.fromJson(nasaJson, NasaResponse::class.java)
                Log.d(TAG,, "LINKS: ${JsonToClass?.links?.self}")
                Log.d(TAG, "COUNT: ${{JsonToClass?.element_count}")

My problem is that the "object_one" arrays always return null.

I have tried many possibilities that I have found in support pages or documentation, but without success.

What is the correct way to get those arrays?

CodePudding user response:

The problem is your definition in your custom class does not match the JSON format.

Beside objet_one mentioned in the comment,

you are using neo instead of near_earth_objects as the variable name.

class NasaResponse(
   val element_count: Int,
   val neo: near_earth_objects, // Wrong name, change neo -> near_earth_objects
   val links: links)

To do it better, I recommend to follow the recommended Java/Kotlin style to name the variables.

Then use the annotations provided by GSON to define the name expected to be seen in the JSON.

e.g.

    class NasaResponse(
    @SerializedName("element_count")
    val elementCount: Int,
    @SerializedName("near_earth_objects")
    val nearEarthObjects: NearEarthObjects,
    val links: links)
  • Related