3

I have a simple button in a form and I would like to show a spinner when I make Axios request. Here's my button with spinner (from loading.io).

<form @submit.prevent="onSubmit" class="form-inline">
  ...
  <button type="submit" class="btn btn-primary mb-5" id="loading" :disabled="loading">
    <div class="lds-ring" v-if="loading"><div></div><div></div><div></div><div></div></div>
    Submit
  </button>
</form>

There is a spinner which I show conditionally when loading is true.

I have defined onSubmit method but where I dispatch an action and change loading to true before the request and to false when the request is complete but it doesn't work. Could you explain me why?

onSubmit()

onSubmit () {
        const formData = {
          start_address: this.start_address,
          destination_address: this.destination_address,
          price_cents: this.price_cents,
          date: this.date
        }
        this.loading = true
        this.$store.dispatch('createRide', formData)
        this.loading = false
      }

create_ride

createRide({ commit }, ride){
    axios.post('/api/trips', ride)
      .then(response => {
        commit('addRide', response.data)
      })
      .then(response => {
        commit('showSuccessAlert')
      })
      .catch(error => {
        commit('showErrorAlert')
      })
jedi
  • 2,003
  • 5
  • 28
  • 66

1 Answers1

4

You need to wait for the promise to resolve when dispatching the api call, as you have it written the loading property is immediately being set to false. Try changing the method to:

async onSubmit () {
    const formData = {
      start_address: this.start_address,
      destination_address: this.destination_address,
      price_cents: this.price_cents,
      date: this.date
    }
    this.loading = true

    // using await
    await this.$store.dispatch('createRide', formData)
    this.loading = false

    // or without await
    this.$store.dispatch('createRide', formData).then(() => {
      this.loading = false
    })
  }

The vuex store action should be updated as well:

async createRide({ commit }, ride){
  await axios.post('/api/trips', ride)
    .then(response => {
      commit('addRide', response.data)
    })
    .then(response => {
      commit('showSuccessAlert')
    })
    .catch(error => {
      commit('showErrorAlert')
    })
})
Brian Lee
  • 17,904
  • 3
  • 41
  • 52
  • I needed to install 2 plugins: "babel-polyfill" and "babel-plugin-transform-regenerator" but it still doesn't work. – jedi Dec 06 '18 at 11:19
  • You'll need to transpile the async/await syntax using webpack and babel or equivalent. Vue cli 3 provides this out of the box. What are you using in your build process? – Brian Lee Dec 06 '18 at 11:23
  • Try with await instead of returning from the vuex action. – Brian Lee Dec 06 '18 at 11:26
  • I have followed this post https://stackoverflow.com/questions/46389267/using-async-await-with-webpack-simple-configuration-throwing-error-regeneratorr and configured webpack.conf.js and .babelrc aoccrdingly – jedi Dec 06 '18 at 11:27
  • I do it like that: `await this.$store.dispatch('createRide', formData)` but no luck still – jedi Dec 06 '18 at 11:28
  • Change the vuex action: `await axios.post('/api/trips', ride)` – Brian Lee Dec 06 '18 at 11:30
  • I have tried both with `await` and without with `.then` and no luck – jedi Dec 06 '18 at 11:30
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/184804/discussion-between-jedi-and-digitaldrifter). – jedi Dec 06 '18 at 11:33
  • Would you explain to me how it all works, please? I am pretty new to this. – jedi Dec 06 '18 at 12:24
  • There are a lot of newer JavaScript features that have limited or no support across the range of browsers and versions out there in the wild, so to ensure functionality for the highest percentage possible, the code is transpiled, or converted so to speak, to [ES5](https://en.wikipedia.org/wiki/ECMAScript). Promises, async/await are a common case. If you want a good, in-depth read I suggest this [site](https://ponyfoo.com/articles/es6-promises-in-depth); well written articles with practical examples. Hope this helps! – Brian Lee Dec 06 '18 at 14:45