Skip to content

vue-router beforeEach function does not return item which is updated

I’m stuck with a problem. So here is the scenario. I put an axios request which takes the access token from cookies on store. Then I committed a mutation to make true isLoggedIn variable. Then I access this variable from Navbar to change menu items. It works. But when I try to access isLoggedIn variable with getters in beforeEach function, it turns still false. But it is true on Navbar.

user/actions.js which I request to backend to for authentication.

import axios from 'axios'

const checkUser = ({ commit }) => {
  axios({
    method: 'get',
    url: 'http://localhost:3000/api/auth/VpW02cG0W2vGeGXs8DdLIq3dQ62qMd0',
    withCredentials: true,
    headers: {
      Accept: "application/json",
    },
  })
    .then((res) => {
      commit('defineUser', res.data)
      return true
    })
    .catch((err) => {
      console.log(err)
      return false
    })
}

export default {
  checkUser,
}

user/mutations.js which I set user and isLoggedIn variables

const defineUser = (state, res) => {
  state.user = res.user
  state.isLoggedIn = true
}

export default {
  defineUser,
}

Then I call that action func in beforeEach in router

router.beforeEach(async (to, from, next) => {
  const accessToken = VueCookies.get('access_token')
  if (accessToken) { // first I check if there is an access token. I do that because I check every request if it is logged in. So I can manage Navbar.
    await store.dispatch('user/checkUser')
    if (store.getters['user/isLoggedIn']) { // HERE IS THE PROBLEM IT TURNS FALSE HERE. if there is an access token, then I check it with if mutation made isLoggedIn true and all doors are open for that user
      next()
    } else { // if it is false then show a toast and remove access token and reload the page
      router.app.$bvToast.toast('You need to log in to see this page!', { // another question, when I deleted async it cannot read toast with only getter. If I put something else it works perfectly.
        title: 'Unathorized',
        variant: 'danger',
        solid: true
      })
      VueCookies.remove('access_token')
      router.go(router.currentRoute)
    }
  } else if (to.meta.requiresAuth) { // so if there is no access token and this page requires auth so show an toast
    router.app.$bvToast.toast('You need to log in to see this page!', {
      title: 'Unathorized',
      variant: 'danger',
      solid: true
    })
  } else { // if no requires auth and no access token then just get in the page
    next()
  }
})

If you need any other information please say, so I can share with you. Any help will be appreciated.

Answer

You are awaiting checkUser but it doesn’t return a promise. Change it to:

const checkUser = ({ commit }) => {
  return axios({    // notice the `return` statement
  ...
}

Alternatively, you could use async/await:

const checkUser = async ({ commit }) => {   // async
  await axios({    // await
  ...
}