Freeptom
Freeptom

Reputation: 23

Vuex - Calling Async Functions

I'm trying to use Vue's Async Actions to make an API call. The problem I'm having is that the data isn't coming back quick enough. The method carries on without waiting for the action's data to return. The first time it's called, this.lapNumber is undefined. A second attempt works as expected.

I'm calling the action with this 'this.getRound(findRound);' in the method below

     getRaceInfo(date) {
      let showModal = false;
      let findRaceName = '';
      let findCircuitName = '';
      let findRound = '';
      let findLapNum = '';
      // iterate through each race to match date of current
      this.allRaces.forEach(el => {
        if (el.date != date) {
          return;
        } else {
          // if date match then give variables values
          findRaceName = el.raceName;
          findCircuitName = el.Circuit.circuitName;
          findRound = el.round;
          this.fetchRoundResults(findRound);
          console.log('after fetch');
          findLapNum = this.lapNumber;
          showModal = true;
        }
      });
      // assign the variables to corresponding data properties
      this.raceName = findRaceName;
      this.circuitName = findCircuitName;
      this.roundNum = findRound;
      this.lapNum = findLapNum;
      return showModal ? (this.isModalVisible = true) : '';
    },

The action that's called is:

  async fetchRoundResults({ commit }, roundNum) {
    try {
      const response = await axios.get(`http://ergast.com/api/f1/current/${roundNum}/results.json`);
      const roundInfo = response.data.MRData.RaceTable.Races[0];
      await commit('set_round_results', roundInfo);
      console.log('set result');
      return response;
    } catch (e) {
      console.log(e);
    }
  },
};

In the console this is what's run based on the console logs:

after fetch

vue.runtime.esm.js?2b0e:619 [Vue warn]: Error in v-on handler: "TypeError: Cannot read property '0' of undefined"

found in

---> <RaceCalendar> at src/components/Calendar.vue
       <App> at src/components/Dashboard.vue
         <App> at src/App.vue
           <Root>
warn @ vue.runtime.esm.js?2b0e:619
logError @ vue.runtime.esm.js?2b0e:1884
globalHandleError @ vue.runtime.esm.js?2b0e:1879
handleError @ vue.runtime.esm.js?2b0e:1839
invokeWithErrorHandling @ vue.runtime.esm.js?2b0e:1862
invoker @ vue.runtime.esm.js?2b0e:2179
original._wrapper @ vue.runtime.esm.js?2b0e:6911
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property '0' of undefined
    at lapNumber (raceCalendar.js?8f5d:13)
    at wrappedGetter (vuex.esm.js?2f62:762)
    at Vue.eval (vuex.esm.js?2f62:95)
    at Watcher.get (vue.runtime.esm.js?2b0e:4473)
    at Watcher.evaluate (vue.runtime.esm.js?2b0e:4578)
    at Vue.computedGetter [as lapNumber] (vue.runtime.esm.js?2b0e:4830)
    at Object.get [as lapNumber] (vuex.esm.js?2f62:564)
    at VueComponent.mappedGetter (vuex.esm.js?2f62:900)
    at Watcher.get (vue.runtime.esm.js?2b0e:4473)
    at Watcher.evaluate (vue.runtime.esm.js?2b0e:4578)
set result

If ran again, there's no undefined error, but still the data isn't being 'set' until after the method has carried on.

after fetch
set result

Any help would be much appreciated!

Thanks :)

Upvotes: 0

Views: 160

Answers (1)

Ahmet Zeybek
Ahmet Zeybek

Reputation: 1224

Change your getRaceInfo method with this

async getRaceInfo(date) {
  let showModal = false;
  let findRaceName = '';
  let findCircuitName = '';
  let findRound = '';
  let findLapNum = '';
  // iterate through each race to match date of current
  for await (let el of this.allRaces) {
    if (el.date != date) {
      return;
    } else {
      // if date match then give variables values
      findRaceName = el.raceName;
      findCircuitName = el.Circuit.circuitName;
      findRound = el.round;
      await this.$store.dispatch('fetchRoundResults',findRound)
      console.log('after fetch');
      findLapNum = this.lapNumber;
      showModal = true;
    }
  }
  // assign the variables to corresponding data properties
  this.raceName = findRaceName;
  this.circuitName = findCircuitName;
  this.roundNum = findRound;
  this.lapNum = findLapNum;
  return showModal ? (this.isModalVisible = true) : '';
},

Upvotes: 1

Related Questions