'React - get data with axios
In my react app that is based on class components, My response API got from open weather fixes after several lags. this is my state
class Weather extends Component {
constructor(props) {
super(props);
this.state = {
weatherData: undefined,
weatherDescription: undefined,
};
}
My thinking was that when my componentDidMount, weather API getting from openWeather and set it in state
componentDidMount() {
axios
.get(
`http://api.openweathermap.org/data/2.5/weather?id=someCityId&units=metric&appid=myApiKey`
)
.then((response) => {
if (response.request.status === 200) {
this.setState({
weatherData: response.data.main.temp,
weatherDescription: response.data.weather[0].description,
weatherTextDisplay: this.state.airConditionsText.filter((item)=>{
return item["id"] === response.data.weather[0].id
})
});
}else{throw Error('No internet')}
})
.catch(error => Error.message)
and I want to update data when the city is changing, in componentDidUpdate the data get again from the openWeather
componentDidUpdate() {
axios
.get(
`http://api.openweathermap.org/data/2.5/weather?id=someCityId&units=metric&appid=myApiKey`
)
.then((response) => {
if (response.request.status === 200) {
this.setState({
weatherData: response.data.main.temp,
weatherDescription: response.data.weather[0].description,
weatherTextDisplay: this.state.airConditionsText.filter((item)=>{
return item["id"] === response.data.weather[0].id
})
});
}else{throw Error('No internet')}
})
.catch(error => Error.message)
}
But the problem is that when my response receives, it faces a lag that causes data jumps several times to previous data and new data until it fixes
Solution 1:[1]
I do not completely understand the question, but this 'lags' because the action of fetching something from an external source is async and needs time to complete.
As for the second 'part' of displaying the loading text you have to set a variable (preferably in state which indicates the loading state of this component)
eg.
constructor(props) {
super(props);
this.state = {
loading: false,
airConditionsText: null,
// Other stuff you have in state
};
}
componentDidUpdate() {
this.setState({loading: true}) // Start of loading
axios
.get(
`http://api.openweathermap.org/data/2.5/weather?id=${this.state.inputId}&units=metric&appid=myApiKey`
)
.then((response) => {
if (response.request.status === 200) {
this.setState({
weatherData: response.data.main.temp,
weatherDescription: response.data.weather[0].description,
weatherTextDisplay: this.state.airConditionsText.filter((item)=>{
return item["id"] === response.data.weather[0].id
})
});
}else{throw Error('No internet')}
})
.catch(error => Error.message)
.finally(() => this.setState({loading: false})) // End of loading
.finally
is being trigger once the async operation (fetching the data from weatherAPI) finishes with either error or success which is the time to stop loading.
Then you can use this.state.loading
in component render to show loading text
eg.
render() {
return (
<div>
{this.state.loading
? <div> Loading... </div>
: <div>{this.state.airConditionsText}</div> // other stuff you want to display
}
</div>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | marc_s |