1
votes

I am having this issue with Vuex:

I am trying to mutate a nested object in my module state. When I do the mutation it sets the value in all the objects nested properties in my module state.

I dynamically set the collection objects. My module state:

collection: [{
    id: 1,
    prop: {
      nestedProp: ""
    }
  },
  {
    id: 2,
    prop: {
      nestedProp: ""
    },
  },
]

When I properly mutate the state in the mutations methods, it duplicates the value:

changeValueById(state) {
    const obj = state.collection.find(obj => obj.id === 1)
    obj.prop.nestedProp = "new value!!"
}

The espected value:

// colletion[0].prop.nestedProp === "new value!!"
// colletion[1].prop.nestedProp === ""
// colletion[2].prop.nestedProp === ""

But I get:

// colletion[0].prop.nestedProp === "new value!!"
// colletion[1].prop.nestedProp === "new value!!" (duplicated)
// colletion[2].prop.nestedProp === "new value!!" (duplicated)

Am I mutating the state in the wrong way? I can't understand why it is duplicating the value y the whole state tree.

1
Maybe try replacing your current mutator function with something like this: state.collection = state.collection.map(item => {if (item.id===1) item.prop.nestedProp = 'new new value'}) Maybe others can confirm, but my suspicion is that there's something about Vue internals that don't let you set state by reference.Matt Habermehl

1 Answers

1
votes

The mutation looks fine. It looks like the child objects in your state (prop) have the same reference. Check the code where you set the prop values. If it looks something like this:

let prop = {nestedProp: ''}
collection = [{id: 1, prop: prop}, {id: 2, prop: prop}] // Using the same instance of prop in each element of the array!

then this would explain the problem. You could fix this by cloning the value each time you set it. Something like:

let prop = {nestedProp: ''}
collection = [{id: 1, prop: JSON.parse(JSON.stringify(prop))}, {id: 2, prop: JSON.parse(JSON.stringify(prop))}]