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 (2015) Using Parcelable Data Retrieving Parcelable Data

Exception caught: No value for temperatureMax

UPDATE: I verified with the devs at Forecast.io that this is a bug in their API. I would still like help on handling these type of API issues in Android SDK with Java.

My app breaks when I run it and I receive the following error:

E/MainActivity´╣Ľ Exception caught: org.json.JSONException: No value for temperatureMax

When investigating the forecast API response, I notice that the very last daily.data object does not include any of the temperature key/value pairs that all previous objects include. For example, below are the last two daily.data objects:

{
time: 1430809200,
summary: "Clear throughout the day.",
icon: "clear-day",
sunriseTime: 1430831446,
sunsetTime: 1430881471,
moonPhase: 0.55,
precipIntensity: 0,
precipIntensityMax: 0,
precipProbability: 0,
temperatureMin: 52.6,
temperatureMinTime: 1430820000,
temperatureMax: 64.87,
temperatureMaxTime: 1430866800,
apparentTemperatureMin: 52.6,
apparentTemperatureMinTime: 1430820000,
apparentTemperatureMax: 64.87,
apparentTemperatureMaxTime: 1430866800,
dewPoint: 48.57,
humidity: 0.73,
windSpeed: 6.24,
windBearing: 245,
cloudCover: 0.01,
pressure: 1011.71,
ozone: 351.08
},
{
time: 1430895600,
summary: "Clear throughout the day.",
icon: "clear-day",
sunriseTime: 1430917782,
sunsetTime: 1430967927,
moonPhase: 0.59,
precipIntensity: 0,
precipIntensityMax: 0,
precipProbability: 0,
humidity: 0.61,
windSpeed: 7.97,
windBearing: 289,
cloudCover: 0.04,
pressure: 1012.47,
ozone: 356.63
}

How can I recover from this error? In Rails, I would use an if statement to disregard null values, but I'm not sure how or where to apply that solution in this case.

My Stormy Github repo: https://github.com/enriquegonzalez/Stormy

Thanks,

Enrique

Nathan Pickard
Nathan Pickard
10,950 Points

I am also receiving the same error Enrique. Perhaps, this really is an error on the Forecast API side.

2 Answers

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Sorry for the trouble here! This is something Pasan pointed out while developing his version of this course for iOS. We need to address this with an add-on video or a short workshop. I'll try to fit that in soon.

I'm looking at the JSON data now on forecast.io and all the daily entries have a temperatureMax value. This may have been an intermittent error.

Steve.

Steve,

You're correct that it's an intermittent problem with the API. To clarify, my question is really about avoiding these types of API issues, which are unfortunately common. If the API issue hadn't resolved itself, what would be a good way to handle the problem. As I mentioned above, in Rails I would implement an if statement to handle null values or non-existing properties, but I'm not well versed enough in Java to apply this solution.

Thanks for the help,

Enrique

Hi Enrique,

Yes, you can add exception handling to your code. This course will show more of that the further on you go. This can take the form of testing for != null within an if statement or by using try/catch blocks.

However, the point of JSON, to some extent, is to provide consistently formatted data so that the testing of each individual component isn't required. The only test should be that the JSON black has been retrieved. After that the consistent formatting can be relied upon.

But, yes, you can surround each getter method's return statement with a test:

    public int getTemperatureMax() {
        if (mTemperatureMax != null) {
            return (int) Math.round(mTemperatureMax);
        } else {
            return 0; // or handle the error however you want
        }
    }

I guess you could do that when you use setTemperatureMax too - it comes to the same.

I hope that helps.

Steve.

Thanks Steve! This is the logic I was looking for, but am having trouble implementing it because mTemperatureMax is a double, not an integer, and apparently double can't be null or use the != operator. This makes me wonder about a couple of things:

1) How do I convert the double to int and make the condition work, and

2) Perhaps the bigger issue is that the forecast.io bug is not returning a null value for temperatureMax, instead it isn't returning temperatureMax at all. I checked in with forecast.io devs and the bug will be resolved soon, but in your opinion, is it worthwhile to do a higher level check using the JSONObject.has method? e.g.

if(JSONObject.has("temperatureMax")) {
    //it has it, do appropriate processing
}

Hi Enrique,

Apologies for the lack of response, I got a notification when Ben posted a moment ago. I must have missed the previous ones.

Apologies, again, that my suggested solution didn't work for you. That's my lack of knowledge showing through!

The return value is (int) Math.round(mTemperatureMax) so maybe there's an iferror test here? Or a try/catch block. The issue is throwing a JSONException so the block can be set to look for that particular error. So:

try {
  // your getTemperatureMax method call
} catch (JSONException e) {
  Log.e(TAG, "Caught a JSON Exception"); // or e.getStackTrace() 
}

But this is specific to that particular method. For a large set of JSON data, it will rapidly become very challenging testing each element being brought back. That's kinda what the JSON feed is supposed to avoid - it should be a consistent retrieval of data, subject to a network connection.

Anything I suggest to solve this problem will only need applying to each and every element within the dictionary and the code will become ridiculous using my suggestions. I'm sure there's a better way of doing this - I'm just not aware of it.

Steve.