I'm using OpenWeatherAPI, i got the fetch working fine. I'm able to useState to put that successful fetch data into the state. The console log shows up and i can see the request made in the network tab.
However there is something funny going on, my .map()ed data isn't rendering every time as i expect it to. I will write the code, press save and it will show up on the screen. However if i refresh page or restart server it just doesn't show up. Sometimes it shows up after a few refreshes.
I'm most likely doing something wrong the hooks system. Please point out what i'm doing incorrectly.
I can't just directly use the list i put in state after the promise is resolved, i need to filter out the response i just set in state and only get the keys/vals i need hence why you see the second state for filteredForecasts. Why is it only periodically working now and then? I feel like i have all the correct null check if statements yet it still doesn't work as expected...
import React from "react";
import WeatherCard from '../WeatherCard';
import "./WeatherList.scss";
const WeatherList = (props) => {
return (
<div className="weather-list-container">
<WeatherCard />
</div>
);
};
export default WeatherList;
import React, { useState, useEffect } from "react";
import "./WeatherCard.scss";
import { getForecast } from "../../api/GET/getForecast";
const WeatherCard = () => {
const [forecasts, setForecasts] = useState([]);
const [filteredForecasts, setFilteredForecasts] = useState([]);
useEffect(() => {
getForecast()
.then((res) => {
const { list } = res;
setForecasts(list);
})
.catch((err) => {
console.log(err);
});
}, []);
useEffect(() => {
if (forecasts.length) {
const uniqueForecasts = Array.from(
new Set(allRelevantData.map((a) => a.day))
).map((day) => {
return allRelevantData.find((a) => a.day === day);
});
setFilteredForecasts(uniqueForecasts);
}
}, []);
const allRelevantData = Object.entries(forecasts).map(([key, value]) => {
const dateTime = new Date(value.dt * 1000);
const day = dateTime.getDay();
const item = {
day: day,
temp: Math.round(value.main.temp),
weatherMetaData: value.weather[0],
};
return item;
});
return filteredForecasts && filteredForecasts.map(({ day, temp, weatherMetaData }) => {
return (
<div className="weather-card">
<div className="day-temperature-container">
<span className="day">{day}</span>
<span className="temperature">{temp}</span>
</div>
<div className="weather-description">
<span
className="icon weather"
style={{
background: `url(http://openweathermap.org/img/wn/${weatherMetaData.icon}.png)`,
}}
/>
<p>{weatherMetaData.description}</p>
</div>
</div>
);
});
};
export default WeatherCard;
import openWeatherConfig from '../../config/apiConfig';
const {baseUrl, apiKey, londonCityId} = openWeatherConfig;
export function getForecast(cityId = londonCityId) {
return fetch(`${baseUrl}/forecast?id=${cityId}&units=metric&appid=${apiKey}`)
.then(res => res.json());
}
setFilteredForecastsin the array.