Passing vuex module state into vue-router during beforeEach

20,296

console.log(store.state.core.authenticated) return false because you not make a login yet.

In your code you not persist user info in anywhere. E.g. using localstorage

Same considerations:

  1. Not use router.app.$store, use store that you import
  2. In your LOGIN_SUCCESS mutation, store login info and token into localstorage
  3. In your beforeEach hook, check localstorage, if was populated with token, get user information and apply the mutation. If not, just call login page

Something like this..

const mutations = {
  [types.LOGIN_SUCCESS] (state, payload) {
    state.token = payload.token
    state.user = payload.user
    state.authenticated = true
    localstorage.setItem('token', payload.token)
    localstorage.setItem('user', payload.user)
  }
}

const actions = {
  [types.LOGIN] (context, payload) {
    return api.getToken(payload).then(response => {
      context.commit(types.LOGIN_SUCCESS, response)
      return response
    })
  }
}

router.beforeEach((to, from, next) => {
    let user = localstorage.getItem('user')
    let token = localstorage.getItem('token')
    if (user && token) {
      store.commit(types.LOGIN_SUCCESS, {token, user})
      next()
    }
    else if (!store.getters.isAuthenticated) {
      store.dispatch(types.LOGIN).then(() => next())
    } else {
      next()
    }
}
Share:
20,296
Adam Hopkins
Author by

Adam Hopkins

class Adam: def __init__(self): self.work = PacketFabric("Mgr Software Engineer") self.oss = Sanic("Core Maintainer") self.home = Israel("Negev") async def run(self, inputs: Union[Pretzels, Coffee]) -> None: while True: await self.work.do(inputs) await self.oss.do(inputs) def sleep(self): raise NotImplemented

Updated on July 09, 2022

Comments

  • Adam Hopkins
    Adam Hopkins almost 2 years

    I am using VueJS in conjunction with vuex and vue-router. I have a vuex module that is making a mutation to its store, and trying to use that to determine whether or not a user is authenticated.

    Here is what my code looks like in relevant part.

    main.js

    import Vue from 'vue'
    import App from './App.vue'
    import store from './store'
    import router from './router'
    
    router.beforeEach((to, from, next) => {
        console.log(router.app) // prints a Vue$2 object
        console.log(router.app.$store) // undefined
        console.log(store.getters.isAuthenticated) // false
        ...
    }
    
    const app = new Vue({
      store,
      router,
      ...App
    })
    
    app.$mount('#app')
    

    /store/index.js

    import Vue from 'vue'
    import Vuex from 'vuex'
    import core from './modules/core'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      modules: {
        core: core
      }
    })
    
    export default store
    

    /store/modules/core.js

    import * as types from '../types'
    import api from '../../api'
    import router from '../../router'
    
    const state = {
      token: null,
      user: null,
      authenticated: false
    }
    
    const mutations = {
      [types.LOGIN_SUCCESS] (state, payload) {
        console.log('mutate')
        state.token = payload.token
        state.user = payload.user
        state.authenticated = true
        router.go('/')
      }
    }
    
    const getters = {
      isAuthenticated: state => {
        return state.authenticated
      }
    }
    
    const actions = {
      [types.LOGIN] (context, payload) {
        api.getToken(payload).then(response => {
          context.commit(types.LOGIN_SUCCESS, response)
        })
      }
    }
    
    export default {
      state,
      mutations,
      actions,
      getters
    }
    

    When I go thru my logic to trigger the LOGIN action, I can see that the mutation executed properly, and when I use the Chrome extension to view the vuex state for my core module, the state for user and authenticated have been properly mutated.

    QUESTION

    It seems like this module just simply has not been loaded by the time the router is running in the .beforeEach loop. Is this true?

    If yes, what are some other suggestions on how to handle this situation? If no, what am I doing incorrect?