I want to implement a login method. My code for it is :
login() {
let user = {
email: this.email,
password: this.password
};
this.$store.dispatch('auth/login', user)
console.log(this.$store.getters['auth/getAuthError'])
},
Where I reach the store and dispatch the login action.
the action in the store looks like this:
login(vuexContext, user) {
return axios.post('http://localhost:8000/api/user/login', user)
.then(res => {
vuexContext.commit('setToken', res.data.token)
vuexContext.commit('setUser', res.data, {root: true})
localStorage.setItem('token', res.data.token)
Cookie.set('token', res.data.token )
this.$router.push('/')
}).catch(err => {
vuexContext.commit('setAuthError', err.response.data)
})
},
In the catch block, if an error happens, I update the state and set authError
property to the error i get.
My problem is that, in the login method, the console.log
statement is executed before the action is actually finished so that the authError
property is the state has not been set yet.
How to fix this issue ?
An action in Vuex is where you perform interaction with APIs and commit mutations. Such interactions are inherently asynchronous.
In Vuex actions are asynchronous. If an action is complete , there is no way to detect that. You can return a Promise to let the calling function know that the action is complete. In the below example myAction returns a Promise.
Mutations are intended to receive input only via their payload and to not produce side effects elsewhere. While actions get a full context to work with, mutations only have the state and the payload .
In Vuex, actions are functions that call mutations. Actions exist because mutations must be synchronous, whereas actions can be asynchronous. You can define actions by passing a POJO as the actions property to the Vuex store constructor as shown below. To "call" an action, you should use the Store#dispatch() function.
Your
action
is returning apromise
so you can console after the promise has been resolved inthen()
block.
login() {
let user = {
email: this.email,
password: this.password
};
this.$store.dispatch('auth/login', user).then(() => {
console.log(this.$store.getters['auth/getAuthError'])
// this.$router.push('/') // Also, its better to invoke router's method from a component than in a store file, anyway reference of a component may not be defined in the store file till you explicity pass it
})
},
OR, you can make login an
async
function &wait
for theaction
till promise returned by action has been resolved
async login() {
let user = {
email: this.email,
password: this.password
};
await this.$store.dispatch('auth/login', user)
console.log(this.$store.getters['auth/getAuthError'])
},
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With