Vue x module Namespace - vue.js

I'm stuck on a problem that I had already encountered and which was resolved with the namespaced but nothing helped.
This is my module:
const Algo1Module = {
namespaced: true,
state: {
questions: {
question1: "test",
question2: "",
question3: "",
question4: "",
question5: "",
question6: ""
}
},
getters: {
getMyQuestions(state) {
return state.questions;
}
}
};
export default Algo1Module; // export the module
This is my index.js from my store:
import Vuex from "vuex";
import createLogger from "vuex/dist/logger";
import algo1 from "#/store/modules/algo1.store";
Vue.use(Vuex);
const debug = process.env.NODE_ENV !== "production";
export default new Vuex.Store({
modules: {
algo1
},
strict: debug,
plugins: debug ? [createLogger()] : []
});
And i try to access to my getters from my component like this :
<script>
import { mapGetters } from "vuex";
export default {
name: "Algo",
computed: {
...mapGetters("Algo1Module", ["getMyQuestions"])
}
};
</script>
But i have an error message in console : [vuex] module namespace not found in mapGetters(): Algo1Module/
I don't understand or I may have made a mistake.
Thank you for the answer you can give me.

It will take name that you set up when imported module, try algo1

Your module name is registered under algo1 name.
If you want to call it Algo1Module then register it in the store like that:
modules: {
Algo1Module: algo1,
}

Related

Vuex store is inaccessible

I made a vuex store:
export const general = {
namespaced: true,
state: {
menuEnabled: true,
headerEnabled: true
},
getters: {
menuState: state => state.menuEnabled,
headerState: state => state.headerEnabled
},
actions: {
setMenuVisibility({commit}, visibility) {
commit('setMenuVisibility', visibility);
},
setHeaderVisibility({commit}, visibility) {
commit('setHeaderVisibility', visibility);
}
},
mutations: {
setMenuVisibility(state, visibility){
state.menuEnabled = visibility;
},
setHeaderVisibility(state, visibility){
state.headerEnabled = visibility;
}
}
}
index.js
import { createStore } from "vuex";
import { auth } from "./auth.module";
import {general} from "./general.module";
const store = createStore({
modules: {
general,
auth
},
});
export default store;
main.js
import router from "./router";
import store from "./store";
createApp(App)
.use(store)
.use(router)
.mount('#app')
After that, I created 2 computed functions in App.vue:
computed: {
menuVisibilityState : function (){
return this.$store.state.menuEnabled;
},
headersVisibilityState : function () {
return this.$store.state.headerEnabled;
}
}
But, I can't get them from vuex:
I tried to import general directly in App.vue and get the values.
It doesn't work and I think, that it's bad way to get them.
Can somebody help me?
When you create a module in Vuex, the local state is nested depending on the name you've provided to the module (this happens when you're accessing the root state.).
In your example, to access the local state of general module you could write:
computed: {
menuVisibilityState : function (){
return this.$store.state.general.menuEnabled;
},
headersVisibilityState : function () {
return this.$store.state.general.headerEnabled;
}
}
Keep in mind that:
actions and mutations are still registered under the global namespace - this allows multiple modules to react to the same action/mutation type. Getters are also registered in the global namespace by default.
https://vuex.vuejs.org/guide/modules.html#namespacing

export 'default' (imported as 'Vue') was not found in 'vue

I'm trying to get the url of the backend, but I get an error while importing and it's not clear how to fix it.
warning in ./src/store/index.js
"export 'default' (imported as 'Vue') was not found in 'vue'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
backendUrl: "http://127.0.0.1:8000/api/v1"
},
mutations: {},
actions: {},
modules: {},
getters: {
getServerUrl: state => {
return state.backendUrl
}
}
})
export default store
working version:
import { createStore } from "vuex";
const store = createStore({
state: {
backendUrl: "http://127.0.0.1:8000/api/v1"
},
mutations: {},
actions: {},
modules: {},
getters: {
getServerUrl: state => {
return state.backendUrl
}
}
})
export default store
If you are using the vue-cli, I have found that the solution is to modify vue.config.js to include the devServer property. See the Vue CLI documentation
module.exports = {
devServer: {
disableHostCheck: true,
proxy: {
'/api-ezbook': {
target: 'http://localhost:80',
ws: false
}
},
public: 'http://localhost:8080'
}
// use to deploy
publicPath: '/'
// use to deploy to live server
// publicPath: '/location/on/server'
// in production:
// publicPath: '/'
}

vuex duplicate namespace auth/ for the namespaced module auth

I am using nuxt.js with the auth module.
Every time i open a new page on my profile this error message appears.
I have created a mixin called auth.js in my plugins/mixins directory. This file contains the code:
export const getters = {
authenticated(state) {
return state.loggedIn;
},
user(state){
return state.user;
}
};
I've created a getter file called auth.js with the following code:
import Vue from 'vue'
import {mapGetters} from 'vuex'
const User = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
user: 'auth/user',
authenticated: 'auth/authenticated'
})
}
})
}
};
Vue.use(User);
The getters and mixin work, but everytime i open a page it gives me this error and i dont know how to solve it. I've tried the solutions in this question:
duplicate namespace auth/ for the namespaced module auth
Altough this does solve the errors, it makes my getters undefined.
Yeah, I found a workable way ...
Switch to index.js auth.js logic, and delete auth.js.
index.js
export const getters = {
authenticated(state) {
return state.auth.loggedIn
},
user(state) {
return state.auth.user
}
}
Revise it as follows if you are using a user.js mixin:
import Vue from 'vue'
import {mapGetters} from 'vuex'
const User = {
install(Vue, options) {
Vue.mixin({
computed: {
...mapGetters({
user: 'user',
authenticated: 'authenticated'
})
}
})
}
};
Vue.use(User);
Plugins:
** Plugins to load before mounting the App
*/
plugins: ["./plugins/mixins/user.js"
],

Why Vuex-persist doesn't store anything in localStorage?

So, in my project (Vue-cli + TypeScript) I need to store user data to locaStorage. For this purpose I decide to use vuex-persist (npm plugin) alongside with vuex. But in DevTool, in localStorage doesn't appear anything. What is wrong in my code. Thank you in advance.
In precedent project I already used this combination of tools, and they work fine. In this project I use the same configuration, and it doesn't work . And this is the most strange thing.
This is StructureModule.ts
import { ActionTree, MutationTree, GetterTree, Module } from "vuex";
const namespaced: boolean = true;
interface IDataStructure {
name: string;
type: string;
description: string;
}
interface IStructureState {
name: string;
description: string;
props: IDataStructure[];
}
export interface IState {
structures: IStructureState[];
}
export const state: IState = {
structures: [
{
name: "",
description: "",
props: [
{
name: "",
type: "",
description: "",
},
],
},
],
};
export const actions: ActionTree<IState, any> = {
addNewDataStructure({ commit }, payload: IStructureState): void {
commit("ADD_DATA_STRUCTURE", payload);
},
updateDataStructure({ commit }, payload: IStructureState): void {
commit("UPDATE_EXISTING_DATA_STRUCTURE", payload);
},
clearDataStructure({ commit }, { name }: IStructureState): void {
commit(" CLEAR_DATA_STRUCTURE", name);
},
};
export const mutations: MutationTree<IState> = {
ADD_DATA_STRUCTURE(state: IState, payload: IStructureState) {
if (state.structures[0].name === "") {
state.structures.splice(0, 1);
}
state.structures.push(payload);
},
CLEAR_DATA_STRUCTURE(state: IState, name: string) {
state.structures.filter((structure: IStructureState) => {
if (structure.name === name) {
state.structures.splice( state.structures.indexOf(structure), 1);
}
});
},
UPDATE_EXISTING_DATA_STRUCTURE(state: IState, payload: IStructureState) {
state.structures.map((structure: IStructureState) => {
if (structure.name === payload.name) {
state.structures[state.structures.indexOf(structure)] = payload;
}
});
},
};
export const getters: GetterTree<IState, any> = {
dataStructureByName(state: IState, structName: string): IStructureState[] {
const structure: IStructureState[] = state.structures.filter((struct: IStructureState) => {
if (struct.name === structName) {
return struct;
}
});
return structure;
},
dataStructures(): IStructureState[] {
return state.structures;
},
};
export const StructureModule: Module<IState, any> = {
namespaced,
state,
mutations,
actions,
getters,
};
This is index.ts
import Vue from "vue";
import Vuex, { ModuleTree } from "vuex";
import VuexPersistence from "vuex-persist";
import { StructureModule , IState} from "./modules/StructureModule";
Vue.use(Vuex);
const storeModules: ModuleTree<IState> = {
StructureModule,
};
const vuexPersistentSessionStorage = new VuexPersistence({
key: "test",
modules: ["StructureModule"],
});
export default new Vuex.Store<any>({
modules: storeModules,
plugins: [vuexPersistentSessionStorage.plugin],
});
This is main.ts
import store from "#/store/index.ts";
import * as $ from "jquery";
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
global.EventBus = new Vue();
(global as any).$ = $;
Vue.config.productionTip = false;
console.log(store);
new Vue({
router,
store,
render: (h) => h(App),
}).$mount("#app");
This is vue.config.js
module.exports = {
transpileDependencies: ["vuex-persist"],
};
This is store in vue-devtool
And this is dev-tool localStorage
I expect that in localstorage to appear an storage with key "test" with predefined values, but instead of this localStorage is empty.
As said in the guide
The only way to actually change state in a Vuex store is by committing
a mutation
https://vuex.vuejs.org/guide/mutations.html
I don't see any mutation in your code.
Otherwise, you should take a look at https://github.com/robinvdvleuten/vuex-persistedstate, it seems to be more popular, and I've been using it without any problem.
Usage is very simple : you just need to declare a plugin inside your store:
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()],
})
I found solution for this problem.
In my case i just remove namespaced from
export const StructureModule: Module<IState, any> = {
namespaced, <----- This
state,
mutations,
actions,
getters,
};
It seems namespaced should be used only if you have more than one module.

Vuex mapstate object undefined and "[vuex] unknown mutation type: "

I'm new with vue.js and vuex and I've an issue with the mapstate object, first I've only one module in my store:
-Store
-index.js
-mutations.js
-actions.js
-state.js
state.js :
export default {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
So when I try to access the userInfo object everything works correctly:
computed: {
...mapState(["userInfo"]),
}
Then I decided to create modules:
-Store
-modules
-ldap.js
-commons.js
-index.js
So the userInfo is in the commons.js file and now when I try to get the object I always get undefined:
commons.js
// state
const state = {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
export default {
actions,
mutations,
state
}
Component.vue
computed: {
...mapState(["userInfo"]), // <---- undefined
}
main.js :
import Vue from 'vue'
import Vuex from 'vuex'
import commons from './commons'
import ldap from './modules/ldap'
Vue.use(Vuex)
export default new Vuex.Store({
modules : {
commons,
ldap
}
})
Can you tell me how to access the userInfo object?
Thanks.
Considering:
Your commons.js is as follows:
// state
const state = {
userInfo: {
messages: [{ 1: 'test', 2: 'test' }],
notifications: [],
tasks: []
}
}
export default {
namespaced: true, // <== make sure this is defined
actions,
mutations,
state
}
And main.js imports it like:
import commons from './commons'
// ..
export default new Vuex.Store({
modules : {
commons,
ldap
}
})
Then update on Component.vue:
import { mapState } from 'vuex'
// ...
computed: {
...mapState('commons', ["userInfo"]), // <== add module name here
}
Or
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('commons')
// ... notice module name above ^^^^^^^^^
computed: {
...mapState(["userInfo"]),
}
"[vuex] unknown mutation type: "
Since you are now namespacing your commons module, that modules' mutations now must be prefixed.
So, say you had a mutation like:
const mutations = {
changeName(state, data) {
state.name = data;
}
}
export default {
namespaced: true,
actions,
mutations,
state
}
And you used it like:
this.$store.commit('changeName', "New Name");
Now use it like:
this.$store.commit('commons/changeName', "New Name");
I guess you have namspaced your modules by adding namespaced: true in your module.
So you should pass the module name as the first argument to the mapState helpers so that all bindings are done using that module as the context. See Binding Helpers with Namespace
computed: {
...mapState('commons' , ["userInfo"])
}
You have to define each module as a individual store, here some pseudo example.
// authStore.js
import mutations from './authMutations'
import actions from './authActions'
import getters from './authGetters'
const initialState = {
...
}
export default {
state: initialState,
mutations,
actions,
getters
}
Then, register the modules
import authStore from './authStore'
const store = new Vuex.Store({
modules: {
{...authStore, namespaced: true},
{...postStore, namespaced: true} // some other module defined like auth
}
})
new Vue({
....
store: store
})
And then, on the component use it:
import { createNamespacedHelpers } from 'vuex'
// map state and actions of the module
const { mapState, mapActions } = createNamespacedHelpers('auth')
export default {
computed: {
...mapState({
prop1: 'prop1'
})
}
}
Vuex modules docs
It is really unclear in the documentation but namespaced: true is required to use the map functions.
At least as of the last comment in this discussion
https://github.com/vuejs/vuex/issues/855
Without the need to namespace your modules you can use the callback variant of mapstate:
computed: {
...mapState({
userInfo: state => state.commons.userInfo,
}),
},