256

Is it possible to dispatch an action between namespaced modules?

E.g. I have Vuex modules "gameboard" and "notification". Each are namespaced. I would like to dispatch an action from the gameboard module in the notification module.

I thought I could use the module name in the dispatch action name like this:

// store/modules/gameboard.js
const actions = {
    myaction ({dispatch}) {
        ...
        dispatch('notification/triggerSelfDismissingNotifcation', {...})
    }
}
// store/modules/notification.js
const actions = {
    triggerSelfDismissingNotification (context, payload) {
        ...
    }
}

But when I try to do this I get errors that make me think Vuex is trying to dispatch an action within my gameboard module:

[vuex] unknown local action type: notification/triggerSelfDismissingNotification, global type: gameboard/notification/triggerSelfDismissingNotification

Is there a way of dispatching actions from a given Vuex module to another, or do I need to create some kind of a bridge in the root Vuex instance?

zcoop98
  • 2,590
  • 1
  • 18
  • 31
Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137

2 Answers2

560

You just need to specify that you're dispatching from the root context:

// from the gameboard.js vuex module
dispatch('notification/triggerSelfDismissingNotifcation', {...}, {root:true})

Now when the dispatch reaches the root it will have the correct namespace path to the notifications module (relative to the root instance).

This is assuming you're setting namespaced: true on your Vuex store module.

zcoop98
  • 2,590
  • 1
  • 18
  • 31
Jake
  • 6,096
  • 1
  • 10
  • 13
  • 64
    This is the only hit on the internet for my search for a solution. Thanks for answering. – Peter Roehlen May 22 '17 at 07:16
  • 1
    @PeterRoehlen The same for me. I'just take a view to official docs and this options is not documented. – Zetch Jul 19 '17 at 13:00
  • 16
    To be fair, it is documented here https://vuex.vuejs.org/en/modules.html at "Accessing Global Assets in Namespaced Modules". Though it is kind of awkward to take in. – Jake Sep 02 '17 at 20:35
  • 5
    I love vue, but it seems to me that vuex adds more layers of difficulty rather than make it simpler. Now I know that this is not the purpose of vuex but still, isn't it annoying that I always need to be aware of some conventions like in this example `notification/trigger`, then if i want it to be a little bit more generic I do ``${NOTIF_TYPE_NAME}/${NOTIF_TRIGGER_ACTION}``, still need the slash, or even create a helper function for this, I feel that when I want my App to be more modular I pay a lot more than I get. This is my opinion – Dima Gimburg Feb 14 '18 at 13:10
  • 17
    You can use `this.dispatch`. It doesn't need `{root: true}`. This is global. – MyounghoonKim Mar 04 '18 at 03:03
  • 13
    No you have to use `{root: true}`. The case you meant is probably dispatching to a child module, which indeed (and obviously) does not need this flag. – kursus Nov 10 '18 at 16:41
  • an update for current Vuex is that to call actions from other modules the called action needs to be marked as a global - https://vuex.vuejs.org/guide/modules.html#register-global-action-in-namespaced-modules – baradhili Feb 07 '21 at 04:27
  • If your modules are *not* `namespaced: true`, then you can just do `dispatch('triggerSelfDismissingNotifcation', {...}, {root:true})` — without the module name in the first param. – Ludolfyn Apr 25 '22 at 18:42
0

dispatch('mobuleB/actionB', null, { root: true })