0

I want to include a simple script in my page that retrieves the weather from an api endpoint and adds it to my page. The error that I get is.

app.js:10 Uncaught TypeError: Cannot read property 'periods' of undefined
    at displayWeather (app.js:10)
    at app.js:13
displayWeather @ app.js:10
(anonymous) @ app.js:13

After the page loads, I can run the displayWeather() function in the console, and the result is added to the DOM at that point.

I've tried moving all of the code into a single function, same result.

const address = 'https://api.weather.gov/gridpoints/LMK/49,64/forecast';
let weather = $.getJSON(address, function(data) {
    weather = data;
});


function displayWeather(){
    $(".weather").html("Current Temperature: " + 
           weather.properties.periods[0].temperature + " F");
    $(".weather").append("</br>" + 
           weather.properties.periods[0].detailedForecast);
};

displayWeather();

This should add the information to the dom on page load, however gives the undefined error. I can run the displayWeather function in the console after page load and it works perfectly.

  • The error means that `weather.properties` is undefined. Probably `weather` doesn't have a property called `properties` when the function is called. – Vencovsky Apr 18 '19 at 11:40
  • Move `$(".weather").html()` underneath `weather = data;`. getJSON is async. So you have to wait for the response to arrive. So what will happen as written is: you create the request for the JSON. You try to update the html, triggering the undefined error. Then the response arrives. Only then is weather set equal to data. You want to make sure you only render the html After the response has arrived. So you have to call displayWeather() inside the getJSON function, not after it. – Shilly Apr 18 '19 at 11:44
  • `$.getJSON(address, function(data) { weather = data; displayWeather(); });` Or even better: `$.getJSON(address, function(data) { displayWeather( data ); });`. Or shorter: `$.getJSON(address, displayWeather );` after updating the weather function to use a parameter. – Shilly Apr 18 '19 at 11:46

2 Answers2

0

Since the weather is something coming from an untrusted source, check for each property like this:

let temperature = weather && weather.properties && weather.properties.periods && weather.properties.periods.length && weather.properties.periods[0].temperature;

if (temperature) {
  $(".weather").html(`Current Temperature: ${ temperature } F`);
}
TJ82
  • 51
  • 4
  • Moving my .html and .append statements directly under the weather = data; line fixed my problem, and let me eliminate several lines of code. Thanks alot!!! Looks like i need to do some more reading on async functions. – Jimmy Morgan Apr 18 '19 at 13:11
0

First of all console the result like

console.log(weather);

and check whether its showing all the objects, then check for the key 'periods'. If the periods value is not null, then it will show current temperature in your html.