Home > Enterprise >  React/js- copy array and edit without editing original array
React/js- copy array and edit without editing original array

Time:07-21

I am trying to filter an array, pass results in new array and edit new array without changes in the original array.

Code looks like this:

const personalDocs = [{
    "IDcard": false,
    "passport": true,
    "documentnumber": "1",
    "dateofissue": ""
}, 
{
  "IDcard": true,
  "passport": false,
  "documentnumber": "2",
  "dateofissue": ""
}];


  const passports = personalDocs.filter((doc) => doc.passport === true);

           const passportsCollection = [...passports];
// tried:  const passportsCollection = passports.slice()

            passportsColection.forEach(object => {
              delete object['IDcard'];
              object.taken = "YES";
          });
 
        console.log("ALL PERSONAL DOCS:")
        console.log(personalDocs)      // this becomes same as passportsCollection :(
        console.log("JUST PASSPORTS")
        console.log(passportsCollection)

Live code available here: https://codesandbox.io/s/agitated-wilson-p9w8kt?file=/src/App.js

Is this related to javascripts basics or react?

Thank you.

CodePudding user response:

This line doesn't do what you think it does:

const passportsCollection = [...passports];

It doesn't clone the items. It creates a copy of the array, but with references to the same objects.

Why? Because objects are passed by reference. So each item in each of the two arrays will be a reference to the same (base) object.

To clone the objects you need to spread each of them:

const passportsCollection = passports.map(i => ({ ...i }));

See it working:

const personalDocs = [{
    "IDcard": false,
    "passport": true,
    "documentnumber": "1",
    "dateofissue": ""
  },
  {
    "IDcard": true,
    "passport": false,
    "documentnumber": "2",
    "dateofissue": ""
  }
];


const passports = personalDocs.filter((doc) => doc.passport === true);

const passportsCollection = passports.map(i => ({ ...i }));
// tried:  const passportsCollection = passports.slice()

passportsCollection.forEach(object => {
  delete object['IDcard'];
  object.taken = "YES";
});

console.log("ALL PERSONAL DOCS:")
console.log(personalDocs) // this becomes same as passportsCollection :(
console.log("JUST PASSPORTS")
console.log(passportsCollection)

Another problem you had was you missed an l when typing passportsCollection.


On a separate note, what you're doing could be streamlined to:

const passportsCollection = personalDocs
  .filter(o => o.passport)
  .map(({ IDcard, ...o }) => ({ ...o, taken: 'YES'}))

const personalDocs = [{
    "IDcard": false,
    "passport": true,
    "documentnumber": "1",
    "dateofissue": ""
  },
  {
    "IDcard": true,
    "passport": false,
    "documentnumber": "2",
    "dateofissue": ""
  }
];

console.log({
  personalDocs,
  passportsCollection: personalDocs
    .filter(o => o.passport)
    .map(({ IDcard, ...o }) => ({ ...o, taken: 'YES'}))
})

CodePudding user response:

It's related to JavaScript basics.

You copied the array, but you didn't copied the object inside of the array.

const copy = passports.map(object => ({ ...object})

Notice that .map and .filter already create a copy of an array so you don't need to do `[...passports]

You can also try using structuredClone

CodePudding user response:

You can use map directly with filter instead of forEach in order to create a new array. you can destruct the object to remove IDcard instead of using delete keyword

.map(({
  IDcard,
  ...object
})

See snippet below

const personalDocs = [{
    IDcard: false,
    passport: true,
    documentnumber: "1",
    dateofissue: ""
  },
  {
    IDcard: true,
    passport: false,
    documentnumber: "2",
    dateofissue: ""
  }
];

const passports = personalDocs.filter(doc => doc.passport).map(({
  IDcard,
  ...object
}) => ({ ...object,
  taken: 'YES'
}));

console.log("ALL PERSONAL DOCS:");
console.log(personalDocs);
console.log("JUST PASSPORTS");
console.log(passports);

  • Related