I\'m looking for a simple solution for the following problem:
I have a Vue component button with which I can make an ajax request. I would like to disable this butto
State.js:
state: {
pendingRequest: false
},
actions: {
fetchRequest: async function(context) {
context.state.pendingRequest = true
let req = await fetch(url)
let data = await req.json()
context.state.pendingRequest = false
}
}
Component.vue:
<button :disabled='$store.state.pendingRequest' @click="$store.dispatch('fetchRequest')">Button</button>
I found another solution: It automatically generates a vuex module for the registered endpoints, watch those endpoints via axios interceptors and sets the proper 'pending' state values based on the status of the related requests.
https://github.com/pharkasbence/pending-request-tracker
Sounds like you want your action to set (commit) a flag when it starts and then clear it when it ends.
Try something like this in Vuex...
state: {
loading: false
},
mutations: {
isLoading (state) {
state.loading = true
},
doneLoading (state) {
state.loading = false
}
},
actions: {
doAjaxRequest ({ commit }) {
commit('isLoading')
return doSomeAjaxRequest().then(res => {
// success
}).catch(err => {
// oh noes
}).finally(() => {
commit('doneLoading')
})
}
}
Now in your component, you can map the loading
state and use it to disable your button, eg
<template>
<button :disabled="loading" @click="doAjaxRequest">Do AJAX!</button>
</template>
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: mapState(['loading']),
methods: mapActions(['doAjaxRequest'])
}
</script>
Alternatively, you can maintain the progress of the request within your component if your action returns a promise (as above). For example, say your button has
<button :disabled="loading" @click="doTheThing">Do the thing!</button>
and
data () {
return { loading: false }
},
methods: {
doTheThing() {
this.loading = true
this.$store.dispatch('someAjaxActionThatReturnsAPromise').finally(() => {
this.loading = false
})
}
}