Suresh Kumar
Suresh Kumar

Reputation: 119

Cannot store and access data from Axios.get in React

As a new user to React, I am trying out a Weather app. My problem is that data is received, but storing and retrieving it. If I store only a few of the values in the data, its working, storing whole object or arrays of arrays don't work. I want to store all data. I don't what is causing the issue.

The code is,

import './Weather.css'
import axios from "axios";
import { useEffect, useMemo, useState } from "react";

const Weather=()=>{
  let bg={background:"url('./images/Weather/sky-sunny.jpg')"}
  let [status, setStatus]=useState([])

  let today=new Date;
  let HourTime=today.getHours()
  let hourTime=(HourTime<13)?(HourTime+" am"):(HourTime-12 +" pm")

  if(HourTime<6 && HourTime>18){
    bg={background:"url('./images/Weather/sky-clear-night.jpg')"}
  }
  
  useEffect(()=>{
    axios.get("https://api.open-meteo.com/v1/forecast?latitude=13.04&longitude=80.23&hourly=temperature_2m,relativehumidity_2m,windspeed_10m")
    .then(res=>setStatus([res.data.hourly.windspeed_10m,
        res.data.hourly.temperature_2m,
        res.data.hourly.relativehumidity_2m]))
    },[])

  return(
    <div className="weatherApp">
      <div className='sky' style={bg}>
        <div className='temperature'>
          <span><h1>{status[1][HourTime]}</h1><h3><sup>o</sup>C</h3></span>
        </div>
      </div>
    </div>
  )
}
export default Weather;

In the above code, I am trying to store 3 arrays from the API data, but I am getting

"TypeError: Cannot read properties of undefined"

But if I use the below code in useEffect, there is no problem.

useEffect(()=>{
  axios.get("https://api.open-meteo.com/v1/forecast?latitude=13.04&longitude=80.23&hourly=temperature_2m,relativehumidity_2m,windspeed_10m")
    .then(res => setStatus([res.data.hourly.windspeed_10m[0],
      res.data.hourly.temperature_2m[0],
      res.data.hourly.relativehumidity_2m[0]])
    )
},[])

I want to store more than 1 value from each array. Does this need a better implementation?

Upvotes: 1

Views: 339

Answers (2)

nart
nart

Reputation: 1848

On initial render status is empty cause status[1] is undefined thus you need to check:

{status[1] && status[1][HourTime]}

Does this need a better implementation?

You can move api function outside of useEffect like this

const WEATHER_API =
  'https://api.open-meteo.com/v1/forecast?latitude=13.04&longitude=80.23&hourly=temperature_2m,relativehumidity_2m,windspeed_10m';

// useCallback to avoid updating on every re-render
const getWeather = React.useCallback(async () => {
  try {
    const response = await axios.get(WEATHER_API);
    setStatus([
      response.data.hourly.windspeed_10m,
      response.data.hourly.temperature_2m,
      response.data.hourly.relativehumidity_2m,
    ]);
  } catch (error) {
    // handle error
  }
}, []);

React.useEffect(() => {
  getWeather();
}, [getWeather]);

Upvotes: 1

Amila Senadheera
Amila Senadheera

Reputation: 13235

Initially status is an empty array. You need to check the length of the array to know whether it is populated by the API call.

Instead of

{status[1][HourTime]}

try like below

{status.length >= 2 && status[1][HourTime]}

Edit tender-wildflower-ngbime

Upvotes: 1

Related Questions