Search code examples
javascriptvue.jsvuex

Vue method not accepting async/await


I am working on a Vue.js project where I am trying to run a series of promises depening on each other. To make this example simple I have cut out all but one and replaced the rest with a console.log which should output the value I am trying to access to then use later on. If I can get this example to work then the rest is just repeating it.

createBuilding: function() {
      return new Promise((resolve, reject) => {
        if(this.building === 'New building') {
          this.$store.dispatch('newBuilding', {
            address: this.address,
            number_units: this.number_units
          })
          .catch(err => {
            reject(err)
          })
          resolve(this.$store.getters.buildingID)
        } else {
          resolve(this.building)
        }
      }) 
    },
    onComplete: async function() {
      let buildingID = await this.createBuilding()
      console.log(buildingID)
      alert('Success');
    },

Real results:

I see the console.log fire off with undefined, then the alert then the awaited promise/function shows in the vue dev tools.

How can I get this so that I can get the result of the createBuilding method to use with my other methods?


Solution

  • This is promise constructor antipattern. There's no need to use new Promise in case a promise already exists and can be chained. The antipattern leaves the space for mistake, which is the case here.

    newBuilding is expected to be asynchronous, but the promise is resolved instantly, this results in race condition.

    It should be:

    createBuilding() {
        if(this.building === 'New building') {
          return this.$store.dispatch('newBuilding',...)
          .then(() => this.$store.getters.buildingID)
        } else {
          return Promise.resolve(this.building)
        }
    },
    

    With async..await, it's simplified to:

    async createBuilding() {
        if(this.building === 'New building') {
          await this.$store.dispatch('newBuilding',...);
          return this.$store.getters.buildingID
        } else {
          return this.building
        }
    },