How to change the vuex-persist key option dynamically? - vue.js

I am using the plugin: https://www.npmjs.com/package/vuex-persist, and it works great. But I am not sure that what I am trying to do will work.
My application has a module of authentication, and the user can create their own settings that are stored in vuex and localstorage. But since there will be different users there will be different settings and that is why each user will have different localStorage, that is why they need to have different name.
In that case I need to change the name of the key setting on the storage plugin dynamically, and I don't know how to do that. The setting for the plugin look like this
import Vue from 'vue'
import App from 'App.vue';
import Vuex 'vuex';
import VuexPersist from 'vuex-persist';
Vue.use(Vuex);
const vuexLocalStorage = new VuexPersist({
key: 'vuex' // I WANT TO CHANGE THIS DYNAMICALLY, how to do that?
storage: window.localStorage, // or window.sessionStorage or localForage
// Function that passes the state and returns the state with only the objects you want to store.
// reducer: state => state,
// Function that passes a mutation and lets you decide if it should update the state in localStorage.
// filter: mutation => (true)
})
const store = new Vuex.Store({
...
plugins: [vuexLocalStorage.plugin]
});
...
new Vue({
store,
el: '#app',
render: h => h(App)
});

Related

Using Vuex State in main js

I am trying to use my store state in main.js but it vanishes my component, can I use state in mian.js
Axios.defaults.headers.common['BranchId'] = this.$store.state.myBrachId,
if not what how can I set the default headers dynamically then..?
You're asking how to access a Vuex store outside a Vue component. The syntax that you're currently using is only valid if you're writing a Vue component.
In case you want to access Vuex outside (any .js file) you should, first, export the store. Then, import that store in your file and finally use the store as you place.
Let's see an example:
store/index.js
export const store = new Vuex.Store({
state () {
myBrachId: 'niceBranch007'
}
});
Then, in any other .js file (main.js in your case)
import { store } from 'store/index.js'
console.log(store.state.myBrachId)
If you're trying to add headers to axios I'd ask you to consider if you should really be getting that header data from a Vuex store anyways. Remember that any browser refresh will clear your store so you should not rely on it's availability more than you need to. Using localStorage or sessionStorage might be better for what you're looking to do here.
I am doing this right now this is my store
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export const store = new Vuex.Store({
state: {
branchId: "",
},
getters:{
},
mutations: {
},
actions: {},
modules: {}
});
In header cmponent
this.$store.state.branchId = this.Branches[index].branchId;
in main js
import Axios from 'axios'
import { store } from './store/index'
Axios.defaults.headers.common['BranchId'] = store.state.branchId;
this is not setting axios header, it comes empty

Vue.js Vuex cannot access store in router

I've seen that this question have been asked a couple of time but I cannot find any good answer and don't understand why my code is behaving like this.
As said in the title I'm trying to import my store in the router to be able to use my getters on conditional and grant a user to access or not a route.
But as soon as i'm trying to import the store I get the following error:
[vuex] unknown action type: autoSignIn
this is coming from:
const vm = new Vue({
router,
store,
provide,
i18n,
render: handle => handle(App),
created () {
firebase.auth().onAuthStateChanged((user) => {
if (user) {
this.$store.dispatch('autoSignIn', user)
this.$store.dispatch('loadMatter')
this.$store.dispatch('loadFootprints')
this.$store.dispatch('loadMembers')
}
})
So I guess that when my app is starting the store hasn't loaded yet.
How can I workaround that I want to be able to use
store.getters.mygetter
Thank you very much
I think you need to import your store in your router file
I'm doing it like this:
import store from "#/store/index.js";
Are you using modules of vuex?
Can you share your store index file?
https://vuex.vuejs.org/guide/modules.html
If you are using modules of vuex, you should do this.$store.dispatch('module_name/action_name')
I have my store split into files
Vue.use(Vuex);
const store = new Vuex.Store({
state,
actions,
mutations,
getters,
plugins: [
process.env.NODE_ENV === 'development' && createLogger({ collapsed: false }),
].filter(Boolean),
});
export default store;

Vue i18n doesn't update in store when switching language in components

I have a store module containing i18n data in state variables:
import i18n from '#/localization';
export default {
state: {
title: i18n.t('title'),
recommendation: i18n.t('recommendation')
...
Problem: in this module, i18n is never updated when user changes language. It is as if the import i18n here was done only once and for all.
How can I make this reactive, so that this store module re-imports i18n every time language changes or updates it properly?
EDIT:
The i18n imported in my store module is the same one that is imported then used in root Vue instance, this is my main.js where you can see the import comes from the same file localization.js:
import i18n from '#/localization';
const vm = new Vue({
router,
store,
i18n,
render: h => h(App)
});

TypeError: Converting circular structure to JSON Vuejs

I am getting the error
"TypeError: Converting circular structure to JSON"
while using vuex-persistedstate plugin.
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
// ...
plugins: [createPersistedState()]
})
I had found some solution to use plugin with no error as below
plugins: [createPersistedState]
But it is not saving the state details.
You haven't mentioned where you want to store the data. Since I am storing vuex data in localStorage my code goes something like:
import createPersistedState from 'vuex-persistedstate'
const store = new Vuex.Store({
// ...
plugins: [createPersistedState(
storage: window.localStorage
)]
})
So basically, just pass storage: window.localStorage to your createPersistedState() method.
Enjoy!

Vuex module not accessible from rootState

I needed to get route's query parameters inside Vuex in order to preload filter settings and update the state of the application. To make this possible I installed vuex-router-sync.
Next step was to synchronize the Vuex and VueRouter.
Router:
Vue.use(VueRouter);
export default new VueRouter({ mode: 'history' });
Store:
Vue.use(Vuex);
export default new Vuex.Store({
modules: { filters: FiltersModule },
plugins: [ FiltersPlugin ]
});
App's bootstrap:
const unsync = sync(store, router);
new Vue({
el: '#restaurant-admin-app',
components: {
'App': AppComponent,
'filters': FilterComponent,
'orders-table': OrdersTableComponent
},
store,
router
});
My FilterPlugin that should trigger the URL parsing:
export default store => {
store.dispatch('filters/parseURLFilterSettings');
}
And now, the funny part, here's the URL parsing action:
parseURLFilterSettings: ({ state, commit, rootState }) {
console.log('RootState:', rootState);
console.log('Route module (incorrect):', rootState.route);
console.log('Filters module (correct):', rootState.filters);
console.log('Object\'s keys:', Object.keys(rootState));
}
What am I doing wrong? I thought it might be something with syncing, but at the end the console.log shows clearly that the route Object is there (and it's not empty), but somehow when I access it, it's undefined. Thank you in advance.
The problem was very well explained here. What it basically says is that the object's value is evaluated when you open it's body in the console.
The problem was I didn't have the route module loaded yet, because I was trying to dispatch an action from a vuex plugin which seems to load before the vuex-router-sync's syncing was done.
The problem was solved when I moved application's bootstrap logic from vuex plugins into the AppRootComponent's mount lifecycle event.
You should import the router-sync. After that your store and routes wil behave properly. I usually do this in the main.js file.
import router from './router'
import store from './store'
import { sync } from 'vuex-router-sync'
sync(store, router)