Reputation: 1323
I've become frustrated with finding an example for what I thought would be a really common use case for something like Vuex.
I dispatch an asynchronous action on the store to populate it via api. Once this store is populated I need to then execute certain operations.
Every Vuex example I come across seems to just deal with a straight update to the UI. But in almost every case I need to also perform key component based operations.
state: {
// initial state values are all falsey
id: false,
name: false,
},
getters: {
getItem: (state) => {
return state;
},
},
actions: {
setItem({commit}) {
// async call to get and then commit the state
}
}
Above is the relevant snippet of the item store a very simple example where the call to dispatch the action is typically called from a component not detailed here. Below is the component where I'm watching for the item to be populated.
watch: {
item: function (newItem) {
this.doSomethingWith(newItem); // this never runs
}
},
computed: {
...mapGetters({
item: 'getItem',
}),
},
mounted() {
console.log(this.item); // I get an observer of the item object
// none of items state properties are defined during mounted
},
methods: {
doSomethingWith(item) {
// I want to do something here with the set item!!
}
}
I expect the items state not to be set on mount as it's an async call to an external api. However what I did expect is when it is eventually populated the watcher would catch that and allow me to run subsequent operations inside the component. However the watch doesn't ever fire.
So how do I track changes like this in components and run operations dependant on their new state?
Upvotes: 4
Views: 4299
Reputation: 82439
The watch never fires because the code is watching the object returned from getItem
, which is the state
object and the reference to the state
object doesn't change. Only the state object's properties change. If you want to fire the watch, you need to perform a deep
watch.
watch: {
item: {
handler:function (newItem) {
this.doSomethingWith(newItem);
},
deep:true
}
},
Depending on your application this might not be very performant. You might want to use a getter that watches a specific property of the state.
Or, return a promise from an action that kicks off the asynchronous API call and do what you need to in a success handler.
Upvotes: 2