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);