Reputation: 1
I have banged my head against all kinds of walls for days and would love some help with this please.
I am getting the following error but can't really see how what I'm doing has anything to do with vuex here:
[vuex] do not mutate vuex store state outside mutation handlers.
In my vue component I define an empty array for future data I get from an external API.
data() {
return {
costCentres: [],
};
},
I have a watch on my vuex store object named schedule
(which I've brought in using MapState... and also tried with a getter using MapGetter to see if that made any difference). In this watch I create my array costCentres, with each element consisting of about five properties from the API. I add two properties at this point (sections and tasks) which I intend to later populate, and which I need to be reactive so I do so in accordance with the Vue reactivity documentation which all the other questions I've found remotely like mine seem to reference.
watch: {
schedule() {
if (this.schedule.rows) {
this.costCentres = this.schedule.rows.filter((row) => {
return row.cells[
this.schedule.columnKeysByName["Cost Code"]
].value; // returns row if Cost Code value exists
});
this.costCentres.forEach((costCentre) => {
this.$set(costCentre, 'section', null);
this.$set(costCentre, 'task', null);
});
}
},
The this.$set
lines throw the earlier mentioned error for every element in the array.
When I later update the properties, the change is reactive so its just the flood of error messages that's got me beat. Obviously if I don't use set
then I don't get reactivity.
I have no idea how what I am doing is related to the vuex store as costCentre
is a plain old data property.
I've tried hundreds of variations to get this all work (including this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
which doesn't seem to work) and I've run out of options so any assistance would be greatly appreciated!
(Please also let me know if I need to show more code - I was trying to keep this concise!)
Upvotes: 0
Views: 1425
Reputation: 37793
this.schedule.rows
is an array containing some objects (mapped from Vuex so the array and objects inside "belongs" to Vuex)this.costCentres
by filter
- so in the end this.costCentres
is just another array containing subset of objects from this.schedule.rows
(elements inside are just pointers to objects inside Vuex)forEach
loop, you are modifying objects which are part of the Vuex store and as a result getting error [vuex] do not mutate vuex store state outside mutation handlers.
If you want to modify those objects, only way is to use Vuex mutations
Alternative solution is to make a copy of objects (create new objects with same values):
this.costCentres = this.schedule.rows.filter((row) => {
return row.cells[this.schedule.columnKeysByName["Cost Code"]].value;
})
.map((row) => ({...row, section: null, task: null }))
Note: code above creates just a shallow copy so if your objects does contain some deeply nested properties, you have to use some other way to clone them
Now objects inside this.costCentres
are not part of the Vuex and can be modified freely without using mutations...
Upvotes: 2