'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