'Vue - How to access component's property from Vuex
In my app I use Vuex to perform async tasks. In this case I use it to log user to my app. When user is logged and axios.then() is being performed I want to inform the component from which I called this.$store.dispatch('login', {username: userObj.username, password: userObj.password}); My component:
data() {
test: false
},
methods: {
login() {
const userObj = {
username: this.username,
password: this.password
};
console.log(userObj);
this.$store.dispatch('login',
{
username: userObj.username, password: userObj.password
});
}
},
Vuex:
const actions = {
login({ commit }, authData) {
axios.post('/login', {
username: authData.username,
password: authData.password
})
.then(resp => {
console.log(resp);
localStorage.setItem('token', resp.data.authToken);
localStorage.setItem('userId', resp.data.id);
localStorage.setItem('user', resp.data);
commit('storeUser', resp.data);
router.replace('/dashboard');
})
.catch(e => {
console.log(e);
alert('Something went wrong, try again')
});
},
}
Here, in .then() method I want somehow to change test property in my component to true. Can someone help me with this one?
Solution 1:[1]
You can return a Promise
from a vuex
action:
const actions = {
login({ commit }, authData) {
return new Promise((resolve, reject) => {
axios.post('/login', {
username: authData.username,
password: authData.password
})
.then(resp => {
console.log(resp);
localStorage.setItem('token', resp.data.authToken);
localStorage.setItem('userId', resp.data.id);
localStorage.setItem('user', resp.data);
commit('storeUser', resp.data);
router.replace('/dashboard');
resolve(resp);
})
.catch(e => {
console.log(e);
alert('Something went wrong, try again')
reject(e);
});
})
},
}
When you dispatch the action you can just treat it like a Promise
(because the return value is a Promise
):
// inside your component
this.
$store.
dispatch('login', {username: userObj.username, password: userObj.password})
.then(resp => { /* do something with axios response using component data and methods*/);
Solution 2:[2]
The whole point of having the Vuex store is not to change your component props/data. Instead, you are supposed to store the data in Vuex and listen to the changes/updates in the component. So, in your login action, you should have something like:
// Commit the changes to the store
commit('storeTest', true);
and then, in the component:
computed: {
// Get the value from the store
test: () => {
return this.$store.test;
}
},
Solution 3:[3]
Vuex actions are thennable, so basically your action dispatch in the component should look something like this:
this.$store.dispatch('login', { username: userObj.username, password: userObj.password }).then(res => {
// response handling
});
Also your action must return the response in order for it to work.
const actions = {
login({ commit }, authData) {
axios.post('/login', {
username: authData.username,
password: authData.password
})
.then(resp => {
console.log(resp);
localStorage.setItem('token', resp.data.authToken);
localStorage.setItem('userId', resp.data.id);
localStorage.setItem('user', resp.data);
commit('storeUser', resp.data);
router.replace('/dashboard');
return resp
})
.catch(e => {
console.log(e);
alert('Something went wrong, try again')
});
},
}
Solution 4:[4]
For mutations ??u can use subscribe or subscribeAction for actions as such:
mounted() {
this.$store.subscribeAction({
before: (action, state) => {
switch (action.type) {
case 'login':
this.test = false;
break;
}
},
after: (action, state) => {
switch (action.type) {
case 'login':
this.test = true;
break;
}
}
});
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | gabriel.hayes |
Solution 2 | Zoran |
Solution 3 | |
Solution 4 |