Skip to content
Advertisement

Race condition with multiple responses from asynchronous axios calls in a vuejs app

I am running multiple axios.get() calls in my Vue.js app. I would like to call another function

this.useData()

after all of the fetches have received responses. How can I do this? I have read about Promise.all(). If this would help me, please advise on how to incorporate Promise.all into my code.

fetchData() {
  for (let j = 0; j < this.selectedLayers.length; j++) {
    if (this.selectedLayers[j].foo == true) {
      axios
        .get("/maps")
        .then(
          response => {
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          },
          error => {
            console.log("error fetching data");
          }
        );
    }
  }
  this.useData();

If I add async and await to my code like below, Vue.js responds with the error…

Can not use keyword ‘await’ outside an async function

  await this.fetchData();
  this.useData();


async fetchData() {
  for (let j = 0; j < this.selectedLayers.length; j++) {
    if (this.selectedLayers[j].foo == true) {
      await axios
        .get("/maps")
        .then(
          response => {
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          },
          error => {
            console.log("error fetching data");
          }
        );
    }
  }

After reading the forum the first answer here recommended, I modified my code to the following…

fetchData() {
  return new Promise(resolve => {
    if (this.selectedLayers[j].foo == true) {
      axios
        .get("/maps")
        .then(
          response => {
            console.log(
              "received response for this.selectedLayers[" + j + "]"
            );
            this.selectedLayers[j].data= response.data;
          },
          error => {
            console.log("error fetching data");
          }
        );
  }
 })};

  let promises = [];
  for (var i = 0; i < this.selectedLayers.length; i++) {
    promises.push(this.fetchData(i));
  }

  Promise.all(promises)
    .then(results => {
      this.useData();
    })
    .catch(e => {
      // Handle errors here
    });

Promise.all() never executes. I imagine there is a nuance with using Promise.all() in tandem with axios.get()?

Advertisement

Answer

Here is a hacky solution you can try. Create a data property named counter and increment it after each axios call has finished. Watch this property and when it reaches the desired counter reset it and call your this.userData() function.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement