Search code examples
javascriptvue.jsvuejs2vuexvue-router

How to access store getter updated value from main.js file in vue app?


I am trying to access updated vuex getter from main.js file to check whether user is logged in or not. Based on that i take user to login page. In the main.js file i simply accessing store getter like this.

var router = new VueRouter({...})

router.beforeEach((to, from, next) => {
    console.log(store.getters['general/isUserLoggedIn'])
    next()
})

general is the module name.

but when simply log store it shows object with updated value. but when logging store.getters['general/isUserLoggedIn'] it shows initial state value. why it is not providing updated value. Is it right way of doing or any alternative way is there.

More details

in store.js file

import Vue from 'vue'
import Vuex from 'vuex'
import general from './modules/general'
import other from './modules/other'

Vue.use(Vuex)

export const store = new Vuex.Store({
    modules: {
        general,
        other
    },
    plugins: [],
    strict: process.env.NODE_ENV !== 'production'
})

checking user logged in or not by calling api status In App.vue file

axios.get('/api/profile').then((response) => {
    if (response.data.status === 'success') {
        this.setUserLoggedIn(true)
    }
})

actions.js in general module

setUserLoggedIn ({ commit }, data) {
    commit(types.SET_USER_LOGGED_IN, data)
}

mutations.js in general module

const mutations = {
    [types.SET_USER_LOGGED_IN](state, data) {
        state.isUserLoggedIn = data
    }
}

Solution

  • On the initial navigation, the login isn't complete yet in the guard, which is why you don't see the value in the console. It only appears true when logging store because it's set shortly after the log, and the console updates itself when you log objects/arrays and then click to view their properties.

    One way to fix the race condition is to redirect to the home page when the login is complete:

    axios.get('/api/profile').then((response) => {
      if (response.data.status === 'success') {
        this.setUserLoggedIn(true)
        this.$router.push('/');  // Route to home page once login is complete
      }
    })
    

    And before that, redirect to login if the user is not logged in:

    router.beforeEach((to, from, next) => {
      const isLoggedIn = store.getters['general/isUserLoggedIn'];
      if(!isLoggedIn) {
        return next('/login');
      }
      next()
    })
    
    • On the initial load, the user will be redirected to the login page.
    • Once the login completes, they will be sent back to the home page.