Md. Jahidul Islam
Md. Jahidul Islam

Reputation: 316

How to copy same object to two variable without mutating each other in Vuex?

What I am trying to do is copying a object to two states using spread operator but when I am changing one of them, other on is also changing.

Actually I am implementing an edit operation for this itemDetails, which is fetched when mounted and have multiple items inside an array. editItemIndex is passed when edit modal for that item is open. After edit item is replaced.

I am trying to copy a duplicate of itemDetails for reset as oItemDetails but the items of oItemDetails are also changed after edit.

please provide me some suggestions for avoiding copy by reference

state: {
    itemDetails: [],
    oItemDetails: [],
    editItem: [],
    editItemIndex: null,
},
actions: {
    async showItemsEditModal ({state, commit}, value) {
      commit('setItemsModalStatus', true);
      state.oItemDetails = await {...value};
      state.itemDetails = await {...value};
    },
    async openEditItemModal ({state, commit}, data) {
      state.editItem = await {...data.data}
      state.editItemIndex = await data.item_index
   },
   async editItem ({state, commit}, data) {
      state.itemDetails.items[state.editItemIndex] = await data
   },
   async resetItem ({state}) {
      console.log(state.itemDetails, state.oItemDetails)
      state.itemDetails = await {...state.oItemDetails}
   }
}

Upvotes: 3

Views: 1334

Answers (2)

joronimo
joronimo

Reputation: 563

To clone an object you need to spread and store it in a variable and use the clone, now you pass a spread as an argument instead of cloning it and passing the clone.

Below a generic example of cloning:

Notice that the clone does not change after the original object is updated.

const exampleObject = {
  title: "Crystal Silence",
  artist: "Chick Corea"
}

// Clone the object

const clone = {...exampleObject};

// NOTE: JSON.stringify is used for display purposes only

let display = "";
display = "Example Object before: " + JSON.stringify(exampleObject) +  "<br/>";
display += "Clone before: " + JSON.stringify(clone) +  "<br/>";

// Now change the exampleObject by adding a new attribute

exampleObject.album = "Return to Forever";

// And check what happens to the clone:

display += "Example Object after: " + JSON.stringify(exampleObject) + "<br/>" ;
display += "Clone after: " + JSON.stringify(clone);

const main = document.getElementById("main");
main.innerHTML = display;
<div id="main"></div>

Upvotes: 2

Hung Nguyen
Hung Nguyen

Reputation: 1156

You need deep clone to avoid copy reference of deep object, use lodash clone deep or JSON.parse(JSON.stringify(value)) instead {...value}.

Note that the performance of JSON.parse and JSON.stringify isn't good, lodash clone deep is a better solution.

Upvotes: 3

Related Questions