I get data from Api but when I try to set the value with useState it give me an empty object

Viewed 31

Hello everyone newbie here! I'm trying to use UseState hook to set setForecastData to the result that I receive from the API call, so then I will be able to access to it and use it elsewhere. After I set a new value to the hook I try to console.log it and it still give me an empty object! I don't know what Im doing wrong in here ? any suggestion is appreciate thanks! ( please see comments on code )

import axios from "axios";
import "./App.css";
import HomePage from "./Components/HomePage";
import MainPage from "./Components/MainPage";
const App = () => {
  const apiKey = process.env.REACT_APP_API_KEY;
  const [input, setInput] = useState("");
  const [city, setCity] = useState("");
  const [matchesArray, setMatchesArray] = useState([]);
  const [locationData, setLocationData] = useState();
  const [forecastData, setForecastData] = useState({});
  //get today weather info
  const getCurrentWeather = () => {
    axios
      .get(
        `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&APPID=${apiKey}`
      )
      .then((res) => {
        console.log(res.data);
        let resp = res.data;
        setLocationData(resp);
      })
      .catch((err) => console.log(err));
  };

  //get weekly weather info
  const getWeeklyWeather = () => {
    let lat = matchesArray[0].lat;
    let lon = matchesArray[0].long;
    axios
      .get(
        `https://api.openweathermap.org/data/2.5/onecall?lat=${lat}&lon=${lon}&exclude=minutely,current&units=metric&appid=${apiKey}`
      )
      .then((res) => {
        const utcOffset = res.data.timezone_offset;
        const hourly = res.data.hourly;
        const daily = res.data.daily;
        let hourlyReduced = hourly.map((hour, index) => ({
          id: index,
          temp: hour.temp,
          weatherCondition: hour.weather[0].main,
          weatherIcon: hour.weather[0].icon,
        }));
        hourlyReduced = hourlyReduced.slice(0, 24);
        const dailyReduced = daily.map((day, index) => ({
          id: index,
          minTemp: day.temp.min,
          maxTemp: day.temp.max,
          weatherCondition: day.weather[0].main,
          weatherIcon: day.weather[0].icon,
        }));

        const forecastInfo = {
          utcOffset: utcOffset,
          hourlyForecast: hourlyReduced,
          dailyForecast: dailyReduced,
        };
        setForecastData(forecastInfo); // NOT WORKING
        console.log(forecastData); // this is not working! it show me an empty object
        console.log(hourlyReduced); // this work fine and it show the result
        console.log(dailyReduced); // this work fine and it show the result
        
        return forecastInfo;
      });
  };
  

  return (
    <div className="App">
      <HomePage
        input={input}
        setInput={setInput}
        city={city}
        setCity={setCity}
        matchesArray={matchesArray}
        getCurrentWeather={getCurrentWeather}
        setMatchesArray={setMatchesArray}
        getWeeklyWeather={getWeeklyWeather}
        locationData={locationData}
        forecastData={forecastData}
      />
      <MainPage locationData={locationData} forecastData={forecastData} />
    </div>
  );
};

export default App;
1 Answers

useState hooks are asynchronous. Logging forecastData right after calling setForecastData will not guarantee that the hook has finished updating the state. Use a useEffect hook to log forecastData whenever it changes.

useEffect(() => {
  console.log(forecastData)
}, [forecastData])
Related