Can I change and commit the state inside settimeout function in Vuex?
Asked Answered
H

1

6
form(@submit.prevent="onSubmit")
   input(type="text" v-model="platform" placeholder="Add platform name...")
   input(type="submit" value="Submit" class="button" @click="clicked = true")
   button(type="button" value="Cancel" class="btn" @click="cancelNew") Cancel      
      h3(v-if="clicked")  Thank you for adding a new platform 
         span {{ countdown }} 

This is my template and when the user submits the form, I want to count down from 3 using setTimeout function and submit after 3 seconds.

If I have it this way, it works;

data() {
  return {
    countdown: 3,
    platform: ""
  }
},
methods: {
  countDownTimer() {
    setTimeout(() => {
      this.countdown -= 1
      this.countDownTimer()
    }, 1000)
  },
  onSubmit() {
    let newplatform = {
      name: this.platform
    }
    this.addPlatform(newplatform)
    this.platform = ' ' 
    this.countDownTimer()
  }
}

However I have 3 more forms and I didn't want to repeat the code. So I wanted to put countdown in the store,

countDownTimer({commit}) {
  setTimeout(() => {
    countdown = state.countdown
    countdown -= 1
    commit('COUNTDOWN', countdown)
    this.countDownTimer()
  }, 1000)
}

and mutate it like

COUNTDOWN(state, countdown) {
  state.countdown = countdown
}

This doesn't work and I am not sure If I am able to change the state, commit the changes inside of settimeout function? Is there a better way I can implement this?

Hypnogenesis answered 9/1, 2021 at 18:45 Comment(0)
E
4

The issues:

  1. The recursive setTimeout isn't stopped.
  2. The countdown timer isn't reset.
  3. Use setInterval (and clearInterval) instead of the recursive setTimeout.
  4. For async logic including setTimeout, use an action rather than a mutation.
  5. Include state from the context object (where you get commit), or it will be undefined.

Try this:

actions: {
  countDownTimer({ state, commit, dispatch }) {  // state, commit, dispatch
    commit('RESET');
    const interval = setInterval(() => {         // Use `setInterval` and store it
      commit('COUNTDOWN');
      if (state.countdown === 0) {
        clearInterval(interval);                 // Clear the interval
        dispatch('updateDatabase');              // Call another action
      }
    }, 1000)
  }
}
mutations: {
  RESET(state) {
    state.countdown = 3;
  },
  COUNTDOWN(state) {
    state.countdown--;
  }
}
Ecclesiolatry answered 9/1, 2021 at 19:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.