Skip to content

module namespace not found in mapState() when using store.registerModule() and non-namespaced module #855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1player opened this issue Jul 7, 2017 · 7 comments

Comments

@1player
Copy link

1player commented Jul 7, 2017

Version

2.3.0

Reproduction link

https://jsfiddle.net/awvv3g60/2/

Steps to reproduce

See fiddle. Notice console error.

What is expected?

mapState to be able to load the state from a dynamically registered, non-namespaced module.

What is actually happening?

Got an error:

module namespace not found in mapState(): inner/
getModuleByNamespace — vuex@2.3.1:792
mappedState — vuex@2.3.1:691
get — vue@2.3.4:2780
evaluate — vue@2.3.4:2880
computedGetter — vue@2.3.4:3132
anonymous — Anonymous Script 1 (line 2)
_render — vue@2.3.4:3901
updateComponent — vue@2.3.4:2443
get — vue@2.3.4:2780
Watcher — vue@2.3.4:2763
mountComponent — vue@2.3.4:2447
_init — vue@2.3.4:4004
Vue$3 — vue@2.3.4:4089
onload — _display:58

This is just bug report #812 reopened with a working JSFiddle link.

The bug is in mapState only, mapGetters, mapActions and mapMutations all work as expected.

Calling mapState without passing a namespace as argument (i.e. mapState(['name']), still does not work. As such, mapState only works with namespaced module.

@ktsn
Copy link
Member

ktsn commented Jul 7, 2017

This is expected. Because namespace value and state path can be different, you need specify namespaced: true when you use mapState with namespace value.

For example:

const store = new Vuex.Store({
  modules: {
    foo: {
      namespaced: false,
      modules: {
        bar: {
          namespaced: true,
          state: { value: 'Hello' }
        }
      }
    }
  }
})

new Vue({
  el: '#app',
  store,
  computed: mapState('bar', ['value'])
})

@ktsn ktsn closed this as completed Jul 7, 2017
@1player
Copy link
Author

1player commented Jul 7, 2017

@ktsn Why do the other map* functions work as expected then? Looks like a bug to me.

The documentation should clarify that mapState only works with namespaced dynamic modules. Sorry I do not have the time to send a pull request.

@ktsn
Copy link
Member

ktsn commented Jul 7, 2017

Other helpers also should not work without namespaced: true option.
I've briefly check it in jsfiddle. https://jsfiddle.net/awvv3g60/3/
If that is the case, could you provide reproduction for it too?

@1player
Copy link
Author

1player commented Jul 7, 2017

They work if you remove the namespace argument from mapGetters: https://jsfiddle.net/awvv3g60/4/

The idea from my point of view is that by registering a non-namespaced module, you want to be able to access state, mutations, etc. as if they were in the root store. So it makes sense that mapGetters works if you do not pass any namespace argument.

The question is, why doesn't mapState work the same way? It's confusing to me, and, if intended (I still can't see why) it should be documented as a gotcha.

To clarify: mapState only works with namespaced modules. Other map* functions work with both.

@ktsn
Copy link
Member

ktsn commented Jul 7, 2017

The map* helpers works as same way - if you pass namespace value, they find corresponding assets from that namespace, otherwise from root namespace. Only difference is the state is registered as tree structure while the other things are registered in root namespace in default.
This is stated in modules section of docs. https://vuex.vuejs.org/en/modules.html

@uriannrima
Copy link

Would it be possible to write something in the module docs to REINFORCE that to use map* helpers with subModules you need to namespace them.

I mean, I've spent a couple of time trying to make an mapping mixin to work, and thought that I was doing something really wrong, until I realized that maybe someone had hit the same rock as I in the issues board.

Well, good to know now. I'll inform that namespaced modules are "mandatory" to use the mixin.

@major-mayer
Copy link

Just if anyone comes accross this, to use mapState with non-namespaced Vuex modules you can use the callback variant of mapState:

...mapState({
      firstItem: (state) => state.firstItem,  // Uses the root state
      secondItem: (state) => state.module.secondItem, // Uses the state of the module
    }),

Shoutouts to this dude here on stackoverflow for his hint 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants