Vuex | How to commit a global mutation in a module action? - vue.js

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 })

Related

Getting unknown local action type in Vuex Store

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.

Nuxt.js Store, dispatch action to other store

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

How do correctly add a getter to a Vuex Module?

I'm trying to create a Vuex module whenever I register the module, I get a state is undefined, even though there is nothing calling the getter I had just made. I'm able to call actions correctly with no errors.
This is my module. customer.js
export default {
namespaced: true,
state: {
login: false,
},
getters: {
isLoggedIn: (state) => {
console.log(state);
state.login;
}
},
mutations: {
set_login: (state, login) => {
state.login = login;
},
set_orders: (state, orders) => {
state.orders = orders;
},
},
actions: {
newsletter_subscribe: (context, email) => {
//- TODO
},
}
}
I have register via the registerModule function.
import Customer from './customer';
store.registerModule('customer', Customer, {
preserveState: true
});
Whenever I have developer tools open it just alerts me that.
Uncaught ReferenceError: state is not defined
at isLoggedIn (customer.js:11)
at wrappedGetter (vuex.esm.js:734)
Am I doing anything wrong with my getter?
I've only noticed the getter being called with Vue Dev tools open as I tried putting an alert in the getter to see what else could be triggering without the state being passed in.
I managed to solve it by giving my store a blank state!
const store = new Vuex.Store({
state: {}
});
And registering modules as normal.

Vuex rootActions with several modules

I have a vuejs on client side, where I use vuex for state management. I have several modules (in separate files) but some of the modules, has very similar actions, that's why I want to create dry code.
My goal: Creating a root action, what can be called by every modules.
My main vuex looks like this:
export default new Vuex.Store({
actions: {
rootactions,
},
modules: {
users,
classes,
studentgroups,
// ... other stuff
}
})
How should I refer the rootactions methods?
Thanks for the responses in advance!
"To dispatch actions or commit mutations in the global namespace, pass { root: true } as the 3rd argument to dispatch and commit."
{
root: true
}
https://vuex.vuejs.org/guide/modules.html
How about to create a separate file RootActions.js with the common actions
export default {
action1: () => {
//
},
action2: () => {
//
},
}
And then import it in your module file e.g. User.js
import RootActions from './RootActions'
const state = {
// state object
}
const mutations = {
// mutations object
}
const actions = {
// actions object
}
export default {
namespaced: true,
state,
mutations,
actions: Object.assign(RootActions, actions)
}

Vuejs simplify vuex action call

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.