Farid
Farid

Reputation: 1665

How to manage state asynchronously in vanilla JavaScript

I am fetching data with

 const getAllCountries = async () => {
    try {
      const response = await axios.get(`/api/cities-list`);
      return response.data;
    } catch (err) {
      return err.response;
    }
  }

 const allCountries = await getAllCountries();

Using vanilla JS, I want to add some kind of loading state for slower connections (or in case the api takes longer than normal to respond). I am doing that with

 const getAllCountries = async () => {
    try {
      document.querySelector('#results').innerHTML = 'Loading'; // Displaying 'Loading' text
      const response = await axios.get(`/api/cities-list`);
      document.querySelector('#results').innerHTML = null;
      return response.data;
    } catch (err) {
      return err.response;
    }
  }

 const allCountries = await getAllCountries();

This works fine on slow connections, but on faster connections, the "Loading" text appears for a split second, then disappears, which is expected.

How can I add some kind of delay (like setTimeout) such that the loading state only displays after 1 second (as an example)? If data is returned prior to 1 second, then don't display the loading state. In other words, users on a fast connection will not see the loading text.

Upvotes: 0

Views: 528

Answers (1)

Ross Mackay
Ross Mackay

Reputation: 972

If you lift response higher in the scope you can access it from within the timeout

const getAllCountries = async () => {

    try {
      let response;

      setTimeout(() => {
        if (!response) {
          document.querySelector('#results').innerHTML = 'Loading'; // Displaying 'Loading' text
        }
      }, 1000)
      
      response = await axios.get(`/api/cities-list`);
      document.querySelector('#results').innerHTML = null;
      return response.data;
    } catch (err) {
      return err.response;
    }
  }

Upvotes: 1

Related Questions