3

Im working in React on some weather widget which displays temp and rain forecast. Im fetching data from OpenWeather and my json response looks like:

//rainy day
0:{
  main: {
    temp:10}
  rain: {
    3h: 1000}
}
//sunny day
1:{
  main: {
    temp:10}
}

the problem is rain.3h property appears in returned response only when it has some data, otherwise its missing. My request looks like:

async getForecast(term) {
  const forecastUrl = "http://api.openweathermap.org/data/2.5/forecast?q=" + term + "&appid=" + apiKey + "&lang=us&units=metric&cnt=16";
  try {
    let response = await fetch(forecastUrl);
    if (response.ok) {
      let jsonResponse = await response.json();
      let forecast = jsonResponse.list.map(
        day => {
          return {
            temp: day.main.temp,
            rain: day.rain["3h"], // can't map missed property
          }
        }
      )
      return (forecast);
    }
  } catch (error) {
    console.log(error);
  }
}

And Im getting error TypeError: Cannot read property '3h' of undefined. How may I add default rain:0 when the property is missing from response

2
  • Hi! Your JSON definitely doesn't look like that, because keys need to be quoted. Can you please post the exact JSON response? Commented Oct 25, 2017 at 18:07
  • yes that was just a shortened version. exact one is screencast.com/t/DX8fMtzqNtD6 Commented Oct 25, 2017 at 18:15

3 Answers 3

1

You could do a check using ternary operator

 let forecast = jsonResponse.list.map(
        day => {
          return {
            temp: day.main.temp,
            rain: day.rain?day.rain["3h"] : ''
          }
        }
      )
Sign up to request clarification or add additional context in comments.

3 Comments

This is the conditional operator. There is no null-coalescing operator (yet) in JavaScript.
Strictly speaking, that's a ternary operator
@lascort yeah sorry
0

You should check whether the property exists or not

var obj = {};
obj.temp = day.main.temp;

if (day.hasOwnProperty("rain") && day.rain.hasOwnProperty("3h"))
  obj.rain = day.rain["3h"];

return obj;

Comments

0

You can use assignment with double ampersand "&&":

let forecast = jsonResponse.list.map(
  day => {
    return {
      temp: day.main.temp,
      rain: day.rain && day.rain["3h"] || 0
    }
  }
)

This works because if day.rain is undefined then the second part of the boolean expression will not be evaluated, avoiding the cannot read property of undefined error, and the value from the OR will be used for default assignment.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.