1

I have an action in my Vuex store that should make a call to the API with new data to be updated.

I want to create an object that is a copy of an existing value in my store and mutate it freely without being impacted by reactivity.

Right now, when I do the Array.push() call, I run into this error

Do not mutate vuex store state outside mutation handlers

how could I do it differently ?

(I have a getter on rootState.phone.policy.currentPolicy.attributes.insured.phones which my explain this error).

  async [PolicyActionTypes.UPDATE_POLICY](
    { rootState },
    payload: UpdatePolicyPayload
  ) {
    const newPolicy: Policy = {
      ...rootState.phone.policy.currentPolicy,
    };

    const newPhone: Phone = {
      imei: '123',
      brand: 'Samsung',
    };

    newPolicy.attributes.insured.phones.push(newPhone);

    // Fake async API call
    api.updatePolicy(newPolicy)
  },
kissu
  • 40,416
  • 14
  • 65
  • 133
Théo Lavaux
  • 1,364
  • 3
  • 22
  • 46
  • 1
    https://stackoverflow.com/questions/52581488/how-can-i-clone-data-from-vuex-state-to-local-data or try lodash.cloneDeep – Mati Dec 17 '21 at 12:03
  • It works thanks, but I don't understand why my answer doesn't? What the difference between the two approaches? – Théo Lavaux Dec 17 '21 at 12:23
  • I believe since `phones` is array, it remains reactive even after the spread. If your object wouldn't be so deeply nested, I would have recommended spreading the phones array instead and adding the new phone to the end of the array. – Mati Dec 17 '21 at 12:36

1 Answers1

1

When you spread, you're making a shallow copy, hence you still reference the old object.
When you do mutate the object, you think that it's a deep copy, while it's still the old one.

More info on my answer here.

TLDR: cloneDeep is the way to go here, indeed.

kissu
  • 40,416
  • 14
  • 65
  • 133
  • I was persuaded that the spread operator created a real copy of the object! Thanks for the insight! I will use the `lodash.cloneDeep` npm package instead of `lodash-es` since I only need this function. – Théo Lavaux Dec 17 '21 at 16:52
  • @ThéoLavaux if you install `lodash-es` but only use `cloneDeep`, it will be exactly the same as `lodash.cloneDeep`. There is no difference size wise in terms of bundle. You do you but I rather install a package once than every time I need a specific function. – kissu Dec 17 '21 at 17:47