Reputation: 497
Imagine, I have a Vue app, required part of which structured like this:
I have three parts. Where:
1. Vue part:
<template>
<div>
<div v-if="displayTable" class="dataTable">
...
</div>
</div>
</template>
<script>
export default {
...
methods: {
getDataset: function() {
this.$store.dispatch('getDataFromDB')
.then(() => {
if (this.$store.state.dataSet.length > 0) {
this.displayTable = true
}
})
}
}
...
}
</script>
2. Vuex part
const actions = {
...
getDataFromDB ({commit}, payload) {
DataSources.apiGetData(payload.querystring)
.then(dataset => commit(GET_DATA, {dataset}))
}
...
}
3. axios part
export const DataSources = {
...
return apiGetData (queryString) {
return axios.get('urlString').then(response => return response.data)
}
...
}
Aim:
I need to retrieve and save data from DB in store's actions and only after that display div.dataTable. And that is Promise's functionality.
Problem:
In my case then()'s part processing first. What should I do to fix it?
Upvotes: 1
Views: 1125
Reputation: 55664
The this.$store.dispatch()
call returns a Promise by default, but because you aren't returning anything in the action being dispatched, the Promise resolves immediately and the then
handler will execute before the async getDataFromDB
action has finished.
You need to return the Promise created by the call to DataSources.apiGetData()
in your getDataFromDB
action:
getDataFromDB ({commit}, payload) {
return DataSources.apiGetData(payload.querystring)
.then(dataset => commit(GET_DATA, {dataset}))
}
This way, the Promise from the action is what is returned by the dispatch
call, and the then
handler won't fire until the async action has resolved.
Upvotes: 3
Reputation: 138
An alternative way to handle this would be to have displayTable
as a computed value, avoiding any issues that may arise from async calls.
<template>
<div>
<div v-if="displayTable" class="dataTable">
...
</div>
</div>
</template>
<script>
export default {
...
computed: {
displayTable() {
return this.$store.state.dataSet.length > 0;
},
},
methods: {
getDataset: function() {
this.$store.dispatch('getDataFromDB');
}
}
...
}
</script>
Upvotes: 2