Helena Sánchez
Helena Sánchez

Reputation: 220

Vuex state does not update without a page refresh

I'm building a single page application where users can see different pages depending if they've logged in or not. The login call works perfectly and an authorization token is saved in the Local Storage.

The setup: I've set up a getter called loggedIn which returns true if a token is set on the state. This is the exact code in my auth.js module of the store:

const state = {
  accessToken: TokenService.getToken(),
}

const getters = {
  loggedIn: (state) => {
    return state.accessToken ? true : false
},

The TokenService has this:

getToken() {
    return localStorage.getItem(TOKEN_KEY)
}

The problem: when the user logs in, the token is correctly saved in the Local Storage (I can see it). However, the Vuex panel in DevTools shows the getter loggedIn as false and the accessToken as undefined. The problem fixes itself when I manually refresh the page. The store is then properly populated.

What am I doing wrong? I need the store to be reactive so I can show some pages or others depending on the loggedIn getter.

Upvotes: 2

Views: 3672

Answers (2)

hamid niakan
hamid niakan

Reputation: 2871

local storage isn't a reactive data so when it changes, there is no way for vuex store to get notified.

what happens is that when your app loads getToken() is called at the very beginning and since user isn't logged in yet it returns undefined, when user logs in, local storage is updated but getToken() doesn't get called again.

BUT! now you have the data in your local storage so when you refresh your page manually getToken() is called and return a Truthy value.

what you can do is to write an action to update accessToken and call it when user is logged in.

something like this:

api.getToken(URL, userData).then((result) => {
   // if user is logged in successfully call the action
   if (result) this.$store.dispatch('auth/updateAccessToken');
})

Upvotes: 2

RuNpiXelruN
RuNpiXelruN

Reputation: 1920

I've run into this problem previously. Sometimes it's just a case of the Vue devtools not refreshing. The state is likely updated as expected. In your loggedIn function, try console logging, ie

loggedIn: (state) => {
    console.log("token:", state.accessToken)
    return state.accessToken ? true : false
}

Vue devtools doesn't do this often. You can right click in the devtool window and refresh frame. It updates your state and corrects itself. An annoying but though

EDIT At the time of successful auth, as well as setting the token in local storage, I would definitely also call a mutation to, at that same point in time, set the accessToken property on the state. You already have it, just set it rather than reading it from localStorage each time. Fetching it from local storage should just be a check you do on first load to see if the user is authed or not..if they are, or once they are, save it to state and access it that way through your app

Upvotes: 0

Related Questions