0

I am attempting to create a weather app using the Openweather API. I am able to retrieve the JSON object successfully, but I am having trouble iterating through the object, I would like to access the weather details for specific dates and times but I just cannot for the life of me wrap my head around the concept. There were times where I was able to access the name of the JSON object, but when I attempt to access a specific weather detail from a specific date and time, I am met with errors constantly. Some of the information is so deeply nested that I am unsure exactly how to retrieve the information

    fetch(`https://api.openweathermap.org/data/2.5/forecast?zip=${zip}&units=imperial&appid=5672e526c1cbc8d71aed230e5e151426`)
      .then(response => response.json())
      .then(json => {
        console.log(json.list);
      });
  }, [apiSearch]);

If I simply try to add an index to the end of json.list:

        console.log(json.list[1]);

I am sometimes met with errors such as Cannot convert undefined or null to object or something along those lines, I would like to know the best way to access the object array below and all of its information, thank you!

Openweather api nested JSON object called by json.list

I've tried multiple approaches including Object.keys, mapping, etc. but I always get hit with an object is null error or something of the sorts. I would like to iterate through the 40 arrays and lets say access the temperature, every attempt to do so has led me to failure. Any help would be greatly appreciated, thank you!

V4k4
  • 33
  • 6
  • You may want to edit your answer and hide your `appId=`, not sure if this is a test key or a public key but either you may want to be more careful about sharing app ids and secrets publicly, otherwise someone may abuse your appId. I would recommend to generate a new one if this is your public key, or restrict it to only be used from certain domain, ip's etc. – cristobal Jul 06 '20 at 22:02

2 Answers2

2

Hope this will help you.

fetch(`https://api.openweathermap.org/data/2.5/forecast?zip=99501&units=imperial&appid=5672e526c1cbc8d71aed230e5e151426`)
      .then(response => response.json())
      .then(json => {
        const forcasetList = json.list;
        forcasetList.forEach(f => {
          console.log(f.main.temp)
        })
      });
Eric
  • 1,279
  • 1
  • 11
  • 8
  • Thank you so much! – V4k4 Jul 06 '20 at 20:51
  • I actually reacieve this error - Unhandled Rejection (TypeError): Cannot read property 'forEach' of undefined (anonymous function) D:/Dev/weather-app/src/containers/WeatherForecast.js:21 18 | .then(response => response.json()) 19 | .then(json => { 20 | const forecastList = json.list; > 21 | forecastList.forEach(f => { | ^ 22 | console.log(f.main.temp) 23 | }) 24 | console.log(json.list) View compiled This screen is visible only in development. It wil – V4k4 Jul 06 '20 at 20:52
  • 1
    You may need to do some exception check in case of null return. Normally if return is a list, you can use forEach. if(forcasetList === null) { console.log('no result') } – Eric Jul 06 '20 at 20:57
  • Thanks was able to fix with `const forecastList = json.list; if (forecastList == null) { return; } else{ forecastList.forEach(f => { console.log(f.main.temp) });` – V4k4 Jul 06 '20 at 21:06
1

There can be several issues here:

Fetch and response status

Since you are using fetch the returned response may not always be a valid response, you should first check that you have an HTTP 200 status response e.g.:

fetch(url).then(
  response => {
    if (response.status !== 200) {
      throw new Error(`Expected status 200 ok got status: ${response.status}`)
    }

    return response.json()
  }
).then(...)

Impartial / Invalid data

I am not familiar with the openweathermap API but from what i can see in the API the forecast list should always have complete non null objects.

But you could add some validation or guards by either e.g.:

  1. Using a JSON schema validation like AVJ
  2. Or having a parse method that checks for the list and returns non null elements
fetch(url).then(
  response => {
    if (response.status !== 200) {
      throw new Error(`Expected status 200 ok got status: ${response.status}`)
    }

    return response.json()
  }
).then(
  forecast => {
    // here you could validate using something like AVJ to
    // check that the json response is valid
    if (!valid(forecast)) {
      throw new Error('Invalid forecast data')
    }

    // Some custom filtering and validation example
    const list = forecast.list || []
    return list.filter(
      item => {
        // filter out null objects
        if (!item) {
          return false
        }
        
        // other validations.
        ...

        // validate the date is within your range
        if (item.dt ...) {
          return false
        }
        
        // valid item
        return true
      }
    )
    .map (
      // extract the weather part
      item => item.weather
    )
  }
).then(
  weatherItems => {
    // work with weather items here
  } 
)
cristobal
  • 462
  • 5
  • 14