Reputation: 220
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
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
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