Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Android Android Lists and Adapters Updating the Data Model From JSONArray to Java Array

questions about the code in this video

Hi, i have questions regarding this code:

     1)   Hour[] hours =  new Hour[data.length()];
     2)   for (int i = 0; i < data.length(); i++) {
          3)  JSONObject jsonHour =  data.getJSONObject(i);

            Hour hour = new Hour();

            hour.setSummary(jsonHour.getString("summary"));
            hour.setIcon(jsonHour.getString("icon"));
            hour.setTemperature(jsonHour.getDouble("temperature"));
            hour.setTime(jsonHour.getLong("time"));
            hour.setTimeZone(timezone);

            hours[i] = hour;
        }

        return  hours;

    }

in line 1 what exactly we are doing?, Ken dosent explain in detail this line..

in line 2 and 3 i understand that we loop through the JSONArray data which contains the temp, time etc.. what exactly "data.getJSONObject(i);" does?

Marie Franklin Steve Hunter

i will appreciate any help..

1 Answer

Hi @noob developer. Here, the key lies in the way the data is "organised" in the API's response, so you can parse that JSON response correctly. Now brace yourself, this answer is pretty long. Sorry, just wanted to be thorough :)

I'd recommend you type this in a browser (adding your API key where I wrote YOUR-API-KEY): https://api.darksky.net/forecast/YOUR-API-KEY/37.8267,-122.4233

This will show you the response to your request to the API. To have a better look (even though it's already formatted in this API) just copy/paste the content in a JSON editor (https://jsoneditoronline.org is pretty good, so let's use it here so you can follow).

In the JSON editor, on the left part of the screen, you will have your JSON response, and on the right part of the screen, you will have that same data edited, so it's easier to see where everything is, and how to get there.

Let's have a look at that right part. At the top, it says object {10}. This is the response object we get when we make a request. {10} tells us it has 10 fields. Reading down, we see: latitude, longitude, timezone, currently, minutely, hourly, daily, alerts, flags and offset. You can see that a few have a little triangle in front of them that let us expand or collapse the field.

Let's click on hourly. Because it says hourly {3}, we know it's an object with 3 fields. Expanding it, we see them: summary, icon and data. Our interest here is data. This time, data has brackets (not braces: {}): data [49], which means it's an array of 49 objects. If we expand, we see the 49 objects, they do not have a name, just an index, from 0 to 48, each containing 18 fields ({18}). If we expand one of those numbered objects, we can see these 18 fields. This is where the data we want is. Now, we do not need everything, we just want time, summary, icon and temperature.

So, when you request data from an API, this is what you have to do:

  • get your JSON response in a browser
  • copy/paste what's on the screen into a JSON editor.
  • look at where the data you want is located
  • establish a path to that data, with the different nodes (the little triangles that let us expand the field) writing whether it's an object or an array.

Now you know how to parse your JSON data.

In our example, to get the data we want (time, summary, icon and temperature), we need to:

  1. get the object object (the response, we stored it in jsonData)
  2. get the object hourly
  3. get the array data
  4. get the time, summary, icon and temperature fields in each object in that data array.

Let's go back to our code.

 private Hour[] getHourlyForecast(String jsonData) throws JSONException {
        // Step 1 - We're naming that response object we got earlier from our API 
        // call `forecast`. This is our root object
        JSONObject forecast = new JSONObject(jsonData); 
        // Calling the getter to get the `timezone` field from that `forecast` object
        // (we'll need that later) 
        String timezone = forecast.getString("timezone"); 

        // Step 2 - Getting the `hourly` object, a field of the `forecast` object
        JSONObject hourly = forecast.getJSONObject("hourly"); 
        // Step 3 - Getting the `data` array, from that `forecast` object
        JSONArray data = hourly.getJSONArray("data"); 

        /*
        We've previously created a model class called Hour. Its fields match the 4 fields
        we're getting from that no-named object from the `data` array, plus `timezone`, 
        that we've already parsed above. Via the editor, we know that the `data` array in
        our JSON response contains 49 objects, but it may change in the future. So here
        we create an array of `Hour` objects, with a length the same length as the `data`
        array in our JSON data response.
        */
         Hour[] hours = new Hour[data.length()]; 


    /*
        We loop through the `data` array to get each no-named object, that we decide to 
        call `jsonHour, calling the getter on that `data` array in our JSON response.
        */
        for (int i=0; i<data.length(); i++) {
            JSONObject jsonHour = data.getJSONObject(i);

            /*
            Step 4- We declare a new `Hour` object, get the value of each of its fields directly 
            from our numbered object in our `data` array of the JSON response (calling the
            specific getter on the jsonHour object) and set it directly. We also add `timezone`,
            which is not in the original numbered object in the `data` array but was previously
            parsed.
            */
            Hour hour = new Hour(); 

            hour.setSummary(jsonHour.getString("summary"));
            hour.setIcon(jsonHour.getString("icon"));
            hour.setTemperature(jsonHour.getDouble("temperature"));
            hour.setTime(jsonHour.getLong("time"));
            hour.setTimezone(timezone);

            // We add our newly created hour object to the hours array.
            hours[i] = hour;
        }
        return hours;
    }

As you can see getting the correct path to the data we want is essential, as we need to know their type to call the correct getter: getJSONObject(), getJSONArray(), getString(), getLong(), etc. If we make a mistake, the JSON parsing will be wrong and we won't get our data.

Sorry for the very long read (have a cookie if you've read until here :) ) but I hope that helped to clarify things