Vuex state on page refresh

Javascriptvue.jsVuejs2StateVuex

Javascript Problem Overview


My app uses the Firebase API for User Authentication, saving the Login status as a boolean value in a Vuex State.

When the user logs in I set the login status and conditionally display the Login/Logout button accordingly.

But when the​ page is refreshed, the state of the vue app is lost and reset to default

This causes a problem as even when the user is logged in and the page is refreshed the login status is set back to false and the login button is displayed instead of logout button even though the user stays logged in....

What shall I do to prevent this behavior

Shall I use cookies Or any other better solution is available...

Javascript Solutions


Solution 1 - Javascript

This is a known use case. There are different solutions.

For example, one can use vuex-persistedstate. This is a plugin for vuex to handle and store state between page refreshes.

Sample code:

import { Store } from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'

const store = new Store({
  // ...
  plugins: [
    createPersistedState({
      getState: (key) => Cookies.getJSON(key),
      setState: (key, state) => Cookies.set(key, state, { expires: 3, secure: true })
    })
  ]
})

What we do here is simple:

  1. you need to install js-cookie
  2. on getState we try to load saved state from Cookies
  3. on setState we save our state to Cookies

Docs and installation instructions: https://www.npmjs.com/package/vuex-persistedstate

Solution 2 - Javascript

When creating your VueX state, save it to session storage using the vuex-persistedstate plugin. In this way, the information will be lost when the browser is closed. Avoid use of cookies as these values will travel between client and server.

import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex);

export default new Vuex.Store({
	plugins: [createPersistedState({
		storage: window.sessionStorage,
	})],
	state: {
        //....
    }
});

Use sessionStorage.clear(); when user logs out manually.

EDIT: Note that if your store have values that are not intrinsically string types (eg dates), your application may fail or behaviour may change because the serialisation/deserialisation process will convert these values to strings.

Solution 3 - Javascript

Vuex state is kept in memory. Page load will purge this current state. This is why the state does not persist on reload.

But the vuex-persistedstate plugin solves this issue

npm install --save vuex-persistedstate

Now import this into the store.

import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    account,
  },
  plugins: [createPersistedState()]
});

It worked perfectly with a single line of code: plugins: [createPersistedState()]

Solution 4 - Javascript

put on state:

producer: JSON.parse(localStorage.getItem('producer') || "{}")

put on mutations:

localStorage.setItem("producer",JSON.stringify(state.producer)) // OR
localStorage.removeItem("producers");

works fine for me!

Solution 5 - Javascript

I think use cookies/localStorage to save login status might cause some error in some situation.
Firebase already record login information at localStorage for us include expirationTime and refreshToken.
Therefore I will use Vue created hook and Firebase api to check login status.
If token was expired, the api will refresh token for us.
So we can make sure the login status display in our app is equal to Firebase.

new Vue({
    el: '#app',
    created() {
        firebase.auth().onAuthStateChanged((user) => {
            if (user) {
                log('User is logined');
                // update data or vuex state
            } else {
                log('User is not logged in.');
            }
        });
    },
});

Solution 6 - Javascript

I've solved this by resetting my headers every time I re-load also fetch user data, I don't know what is better ...

new Vue({
	el: 'vue',
	render: h => h(VueBox),
	router,
	store,

	computed: {
		tokenJWT () {
			return this.$store.getters.tokenCheck
		},
	},


	created() {
		this.setAuth()

	},

	methods:
		Object.assign({}, mapActions(['setUser']), {

			setAuth(){
				if (this.tokenJWT) {
					if (this.tokenJWT === 'expired') {
						this.$store.dispatch('destroyAuth')
						this.$store.dispatch('openModal')
						this.$store.dispatch('setElModal', 'form-login')

					} else {
						window.axios.defaults.headers.common = {
							'Accept': 'application/json',
							'Authorization': 'Bearer ' + this.tokenJWT
						}
						axios.get( api.domain + api.authApi )
							.then(res => {
								if (res.status == 200) {
									this.setUser( res.data.user )
								}
							})
							.catch( errors => {
								console.log(errors)
								this.destroyAuth()
							})
					}
				}
			}
		})

})

Solution 7 - Javascript

Here's how to do it with the composition api.

npm install --save vuex-persistedstate

import createPersistedState from "vuex-persistedstate";
import { createStore } from "vuex";

export default createStore({
  state: {
    project_id: 1,
  },
  mutations: {
    setProjectId(state, payload) {
      state.project_id = payload;
    },
  },
  getters: {},
  actions: {},
  plugins: [createPersistedState()],
});

Solution 8 - Javascript

In this case, the easiest way is installing npm install --save vuex-persistedstate
Then, Importing it into your vuex file import createPersistedState from "vuex-persistedstate"; Then, just put it in your createStore like:

plugins: [createPersistedState()],
    state(){
        return{
            isActive: false,
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionboomboxboyView Question on Stackoverflow
Solution 1 - JavascriptsobolevnView Answer on Stackoverflow
Solution 2 - JavascriptJames WestgateView Answer on Stackoverflow
Solution 3 - JavascriptRijoView Answer on Stackoverflow
Solution 4 - JavascriptLeonardo FilipeView Answer on Stackoverflow
Solution 5 - JavascriptAndrew - oahehcView Answer on Stackoverflow
Solution 6 - JavascriptAlenn G'KarView Answer on Stackoverflow
Solution 7 - JavascriptSpudneck DanView Answer on Stackoverflow
Solution 8 - JavascriptUlugbek MannopovView Answer on Stackoverflow