I am building an app with Vue.js, Vuex, and Firebase. In this app, data from Firestore database is updated to the state in mutations. The app in its current form seems to work fine as the state is then returned to the template by way of the getters method. However, it is my understanding that mutations are synchronous and promises (.then) are asynchronous. Therefore, the .then promise should NOT be inside mutations. So why does this app still execute properly? What would be the best way to reconfigure mutations so that FB data is updated to the state without a promise? Or is it even necessary to change this? Here is my Vuex code. Thanks!
import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase'
import db from '@/firebase/init'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
items: null
},
getters: {
getItems: state => {
return state.items
}
},
mutations: {
setAllUser: state => {
const items = []
db.collection('users').get()
.then(snapshot => {
snapshot.forEach(doc => {
let userData = doc.data()
userData.id = doc.id
items.push(userData)
})
state.items = items
})
},
actions: {
setAllUser: context => {
context.commit('setAllUser')
}
}
})
**SOLUTION**
import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase';
import db from '@/firebase/init'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
items: null
},
getters: {
getItems: state => {
return state.items
}
},
mutations: {
setAllUser: (state, items) => {
state.items = items
}
},
actions: {
setAllUser: async context => {
let snapshot = await db.collection('users').get();
const items =[]
snapshot.forEach(doc => {
let userData = doc.data()
userData.id = doc.id
items.push(userData)
})
context.commit('setAllUser', items)
}
}
})
Move your async code to actions:
{
mutations: {
setAllUser: (state, items) => state.items = items
},
actions: {
setAllUser: async context => {
let snapshot = await db.collection('users').get();
let items = snapshot.map(doc => {
let userData = doc.data();
userData.id = doc.id
return userData;
});
context.commit('setAllUser', items)
}
}
So for the question why?
Why it works?
window.store.state.items = []
. Vuex just overrides getters and updating the state fires updating the dom. PS You can use promise.then
inside your action instead of await
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.