I have two stores on my Nuxt.js app and I need to dispatch an action to another store.
export const actions = {
addToCart({ state, commit, dispatch }) {
dispatch('CartLoadingStore/enableLoadingBar')
this.$axios
.post('something')
.then(response => {
(...)
dispatch('CartLoadingStore/disableLoadingBar')
})
},
}
It seems to me like I cannot dispatch an action to a different store. Is that right? Or is there a way to do so?
The above will result in the error:
[vuex] unknown local action type: CartLoadingStore/enableLoadingBar, global type: StoreTheActionDispatchedFrom/CartLoadingStore/enableLoadingBar
You need to add root param to your dispatch call
dispatch('CartLoadingStore/disableLoadingBar', null, { root: true })
Here docs
Related
I have broken up my Vuex store into namespaced modules.
I have created a User module, where I need to call my Showrooms module. The interesting thing, is that this action works fine. But I am updating the store:
dispatch('showrooms/updateLocalShowroom',
{
weddingId: element.wedding.id,
showroomDresses: element.showroom.showroomDresses,
status: element.showroom.status,
uuid: element.showroom.uuid,
},
{
root: true
}
)
But when I try and reset the Showrooms store with this:
dispatch('showrooms/resetShowrooms', { root: true })
I get the following error:
[vuex] unknown local action type: showrooms/resetShowrooms, global type: user/showrooms/resetShowrooms
The only thing I can think of is something is that when I resetShowrooms I do it like this in my store module:
This action:
resetShowrooms: ({ commit }) => {
commit('zeroOutShowrooms')
},
Calls this mutation
zeroOutShowrooms: (state) => {
Vue.set(state, 'showrooms', [])
}
It ends up that dispatch is looking for some data in the second position. That's why this was NOT working:
resetShowrooms: ({ commit }) => {
commit('zeroOutShowrooms')
},
While this DID work and solved my issue:
dispatch('showrooms/resetShowrooms', '', { root: true })
Just sending the empty string did the trick and all is good now.
I want to display a loading effect in a vue template whilst an asynchronous action in vuex is still running. But the loading effect doesn't seem to work. How do I fix it?. Is there any better way I can achieve this?
This is how I defined the action:
actions: {
signIn({ state }, user) {
auth()
.signInWithEmailAndPassword(userInfo.email, userInfo.password)
.then(result => {
return result
})
},
},
This how defined the dispatch in vue template method:
let loader = this.$loader.show()
this.$store.dispatch('signIn', this.user).then(() => {
loader.hide()
})
I expected the loader to start when the action begins and end when the action ends but it starts and ends almost instantly.
Just add return statement, that returns a Promise so you can then it in your component.
actions: {
signIn({ state }, user) {
return auth()
.signInWithEmailAndPassword(userInfo.email, userInfo.password)
.then(result => {
return result
})
},
},
I have a beforeEach route guard that calls fetchWorkspaces action. This action performs a request to Axios and its response populates the state.
However, when the state is called from the created hook in the component and I refresh the page I do not get the values in the console, but the observer instead.
created() {
console.log(this.workspace) # returns {__ob__: Observer}
}
The action is returning a promise but the created hook is not waiting for that promise to resolve.
This is the hook from the router:
router.beforeEach((to, from, next) => {
store.dispatch('fetchWorkspaces').then(() => {
next()
})
}
And this is the action and its mutation:
export default {
state: {
workspaces: []
},
mutations: {
SET_WORKSPACES(state, workspaces) {
state.workspaces = workspaces.workspaces
}
},
actions: {
fetchWorkspaces({ commit }) {
return Vue.axios.get('/workspaces').then(response => {
commit('SET_WORKSPACES', response.data)
})
}
}
The created is called after the beforeEach hook. I do not understand why this behavior is happening and how to fix it.
The reason I want to get access the newly state data from created is to call other actions that will fetch resources based on this state data.
See this and that. I think the Vue is created first before your router register beforeEach. So, you should use beforeEach before you initiate Vue instance.
I have an action in a namespaced module and a global mutation (i.e. not in a module). I would like to be able to commit the global mutation inside the action.
// Global mutation
export default {
globalMutation (state, payload) {
...
}
}
// Action in a namespaced module
export default {
namespaced: true,
actions: {
namespacedAction ({ commit, dispatch, state }, payload) {
commit({ type: 'globalMutation' })
}
}
}
When the namespaced action is dispatched, Vuex displays:
[vuex] unknown local mutation type: globalMutation, global type: module/globalMutation
Is there an option I can pass to the commit function to call this global mutation?
Looks like I just found a way with the { root: true } parameter.
commit('globalMutation', payload, { root: true })
If module is namespaced, use global path instead:
commit('module/mutation', payload, { root: true })
I am calling a store action through a component like:
sublitPost(){
this.$store.dispatch({type:"submitPost", userPost:this.newPost});
}
and the store action looks like this:
actions: {
submitPost({commit, state}, userPost: any) {
/...rest code here
Although, I would like to simplify this and call the action like:
sublitPost(){
this.$store.dispatch("submitPost", this.newPost);
}
What is the tweak in the action's signature I have to do? What I've tried is to have the action like:
actions: {
submitPost(userPost: any) {
console.log({userPost})
/...rest code here
but in this case, the received object doesn't look correct. What I get in the console log is:
Any help is welcome
You should change your syntax:
actions: {
submitPost(state, data) {
console.log(data)
{
I have divided my store into modules so I am exporting my all mutations, actions, getters.
I am committing a mutation from my action with payload,here payload is an object with property currentWidth
export function fetchDeviceCurrentWidth ({ commit, state }, payload) {
commit('updateDeviceCurrentWidth', payload)
}
My mutation
export function updateDeviceCurrentWidth (state, payload) {
state.currentDeviceWidth = payload.currentWidth
}
My getter
export const currentDeviceWidth = state => state.currentDeviceWidth
This is from where I am dispatching an action:
myEventHandler () {
this.$store.dispatch('fetchDeviceCurrentWidth', {
currentWidth: window.innerWidth
})
}
There are many ways to use vuex store, but I like to break store into modules depending on features or Components.