'fetching from an api - state react context
I am working on an app that fetches current weather for a specified location.
I want to display current time but i have to use "slice()" method to get rid of the first part of the string that looks like this: "localtime: '2022-05-12 13:39' ".
The problem is with useEffect()
and states in the context file.
import axios from "axios";
import { createContext, useEffect, useState } from "react";
const Context = createContext({
weather: {},
place: {},
});
export const ContextProvider = ({ children }) => {
const [weather, setWeather] = useState({});
const [place, setPlace] = useState({});
useEffect(() => {
const getWeatherData = async () => {
try {
const request = await axios.get(
"http://api.weatherstack.com/current"
);
const currentWeather = request.data.current;
const currentPlace = request.data.location;
setWeather(currentWeather);
setPlace(currentPlace);
} catch (err) {
console.log(err);
}
};
getWeatherData();
}, []);
console.log(weather);
console.log(place);
const context = {
weather,
place,
};
return <Context.Provider value={context}>{children}</Context.Provider>;
};
export default Context;
When i console.log my states (lines 33 & 34 in context file) i get this result:
result
So on the first render they're undefined but then useEffect runs and update them.
I assume that this is why my "splice()" method does not work properly.
import styled from "styled-components";
import IconWind from "../icons/icon-wind";
import IconWindDirection from "../icons/icon-wind-direction";
// import IconHumidity from "../icons/icon-humidity";
import { useContext } from "react";
import Context from "../../store/context";
const WeatherDisplay = () => {
const current = useContext(Context);
const currentDay = new Date(current.place.localtime).toLocaleString("en-us", {
weekday: "long",
});
const currentTime = current.place.localtime.slice(10);
return (
<Wrapper>
<div>
<PrimaryInfo>
<h1>{current.place.name},</h1>
<h2>{current.weather.temperature}°</h2>
<p>
{currentDay}, {currentTime}
</p>
</PrimaryInfo>
<AdditionalInfo>
<p>
<IconWind /> Wind Speed: {current.weather.wind_speed}
</p>
<p>
<IconWindDirection /> Wind Direction: {current.weather.wind_dir}
</p>
<p>Atmospheric pressure: {current.weather.pressure}</p>
<p>Humidity: {current.weather.humidity}</p>
</AdditionalInfo>
</div>
</Wrapper>
);
};
const Wrapper = styled.section`
width: 50%;
border-radius: 10px 0 0 10px;
& > div {
height: 100%;
padding-left: 4rem;
display: flex;
justify-content: center;
flex-direction: column;
}
`;
const PrimaryInfo = styled.section`
margin-bottom: 10rem;
h1 {
font-size: 5rem;
}
h2 {
font-size: 4rem;
margin: 1rem 0rem;
}
p {
font-size: 2.4rem;
}
`;
const AdditionalInfo = styled.div`
p {
margin: 1rem 0rem;
font-size: 1.2rem;
display: flex;
align-items: center;
}
`;
export default WeatherDisplay;
splice logs
I tried to check if they already have content but still didnt work:
import styled from "styled-components";
import IconWind from "../icons/icon-wind";
import IconWindDirection from "../icons/icon-wind-direction";
// import IconHumidity from "../icons/icon-humidity";
import { useContext } from "react";
import Context from "../../store/context";
const WeatherDisplay = () => {
const current = useContext(Context);
let currentDay;
let currentTime;
if (current.place.length > 0 && current.weather.length > 0) {
currentDay = new Date(current.place.localtime).toLocaleString("en-us", {
weekday: "long",
});
currentTime = current.place.localtime.slice(10);
}
console.log( currentDay);
console.log( currentTime);
return (
<Wrapper>
<div>
<PrimaryInfo>
<h1>{current.place.name},</h1>
<h2>{current.weather.temperature}°</h2>
<p>
{currentDay}, {currentTime}
</p>
</PrimaryInfo>
<AdditionalInfo>
<p>
<IconWind /> Wind Speed: {current.weather.wind_speed}
</p>
<p>
<IconWindDirection /> Wind Direction: {current.weather.wind_dir}
</p>
<p>Atmospheric pressure: {current.weather.pressure}</p>
<p>Humidity: {current.weather.humidity}</p>
</AdditionalInfo>
</div>
</Wrapper>
);
};
const Wrapper = styled.section`
width: 50%;
border-radius: 10px 0 0 10px;
& > div {
height: 100%;
padding-left: 4rem;
display: flex;
justify-content: center;
flex-direction: column;
}
`;
const PrimaryInfo = styled.section`
margin-bottom: 10rem;
h1 {
font-size: 5rem;
}
h2 {
font-size: 4rem;
margin: 1rem 0rem;
}
p {
font-size: 2.4rem;
}
`;
const AdditionalInfo = styled.div`
p {
margin: 1rem 0rem;
font-size: 1.2rem;
display: flex;
align-items: center;
}
`;
export default WeatherDisplay;
It just displays currentDay and currentTime as undefined.
What am I doing wrong?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|