Reputation: 973
I have a system where I am authenticating and storing user data in Vuex and then validating which views to show or not. I have a property named LoggedIn which is simply a boolean to check if user is logged in or not. let me show you the Vuex parts first
Actions.js
async login({ commit }, loginData) {
const email = loginData.user.email;
try {
commit(USER_REQUEST_START);
const response = await apolloClient.mutate({
mutation: loginAccount,
variables: { email: email },
});
router.push({ name: "Dashboard" });
commit(SET_USER, response.data);
Vue.prototype.$snotify.success("Login Successfully", {
showProgressBar: true,
timeout: 2000,
});
} catch (error) {
commit(USER_REQUEST_ERROR, error);
Vue.prototype.$snotify.error(error.message || "Some thing went wrong", {
showProgressBar: true,
timeout: 2000,
});
}
},
mutations.js
import defaultState from './state'
const mutations = {
SET_USER(state, value) {
state.data = value
state.loggedIn = true
state.loading = false
},
}
export default mutations
login.vue
async submitForm() {
try {
const data = await this.$firebase
.auth()
.signInWithEmailAndPassword(this.email, this.password)
const idTokenResult = await data.user
.getIdTokenResult()
.then((data) => data)
const authTime = idTokenResult.claims.auth_time * 1000
const sessionDuration = this.getSessionDuraion(
authTime,
SESSION_EXPIRE_DAYS,
)
const millisecondsUntilExpiration =
new Date(sessionDuration).getTime() - authTime
this.$store.dispatch('setUserSession', sessionDuration)
setTimeout(() => {
this.$firebase.auth().signOut()
}, millisecondsUntilExpiration)
this.$store.dispatch('login', data)
} catch (error) {
this.$snotify.error(
(error && error.message) || 'Some thing went wrong',
{
showProgressBar: true,
timeout: 2000,
},
)
}
},
this login method validates user sets User State in Vuex and should redirect to dashboard(this is the problem) there is where the below vuejs router action is called
router.js
router.beforeEach((to, from, next) => {
const isAuthenticated = store.state.user.loggedIn
const requiresAuth = to.matched.some((record) => record.meta.requiresAuth)
console.log(store.state.user);
console.log(store.state.user.loggedIn);
if (requiresAuth && !isAuthenticated) {
next({name: 'Login'})
} else {
if (store.state.user.sessionTimeOut && !store.getters.isSessionValid) {
sessionMixin.methods.clearSessionStorage()
next({name: 'Login'})
} else {
next(true)
}
}
})
this is where I am running into a problem, router.beforeEach is simply used to logged out if not authenticated and other processes. Now when i login the user set the state there is no error though, but a very wierd issue, the condition isAuthenticated doesnot work and when i try to console log it it returns false the funny part is when I console.log the actual object i do get the correct value please see the below image for more clarification
extremely Odd behavior dont know whats the reason for doing this, can anyone help me out?
Upvotes: 2
Views: 278
Reputation: 63059
You are redirecting to the dashboard before setting the user, which will trigger the loggedIn
check before it's ready.
router.push({ name: "Dashboard" });
commit(SET_USER, response.data);
As for the console behavior, when logging an object or array to the console, when you click to expand/view the properties, the console shows you the properties as they are at the time of the click, not the time of the log. This is possible because JavaScript objects and arrays are references, so the console is able to update the display by reference.
Here's an illustrative demo of that in action.
(Converted from my comment as requested.)
Upvotes: 2