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?
In Vuex, mutations are synchronous transactions: store. commit('increment') // any state change that the "increment" mutation may cause // should be done at this moment. To handle asynchronous operations, let's introduce Actions.
As specified in the HTML standard, browsers will enforce a minimum timeout of 4 milliseconds once a nested call to setTimeout has been scheduled 5 times.
The setTimeout function runs only once per call, meaning that after the execution of the callback function completes, setTimeout has finished its job. Note: For a countdown that restarts automatically, executing the callback function several times with a timed break between each execution, please see setInterval().
The issues:
setTimeout
isn't stopped.setInterval
(and clearInterval
) instead of the recursive setTimeout
.setTimeout
, use an action rather than a mutation.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--;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With