'How to add a property to my object using a map
I want to add this "visible" attribute and change my "countries" array, "el2" is being changed correctly, but my array at the end is not as expected.
The elements are entering the conditionals and being added to the new property, but at the end of the loop the array is not coming out as expected
const countryVisible: any = ['EUA', 'CANADA']
const countries: any = [{name: 'EUA', id: '123'}, {name: 'CANADA', id: '321'}, {name: 'Italia', id: '322'}]
countries.map((el2, index2) => {
countryVisible.forEach((el, index) => {
if (el2['name'] === el) {
el2 = {...el2, visible: true}
console.log(el2) // {name: 'EUA', id: '123', visible: true} and {name: 'CANADA', id: '321', visible: true}
} else {
el2 = {...el2, visible: false}
console.log(el2) //{name: 'Italia', id: '322', visible: false}
}
})
})
console.log(countries)
output:
[
{
"name": "EUA",
"id": "123"
},
{
"name": "CANADA",
"id": "321",
"visible": false
},
{
"name": "Italia",
"id": "322",
"visible": false
}
]
output expected :
[
{
"name": "EUA",
"id": "123",
"visible": true
},
{
"name": "CANADA",
"id": "321",
"visible": true
},
{
"name": "Italia",
"id": "322",
"visible": false
}
]
Solution 1:[1]
You can replace forEach loop with .includes method
const countryVisible = ['EUA', 'CANADA'];
const countries = [{name: 'EUA', id: '123'}, {name: 'CANADA', id: '321'}, {name: 'Italia', id: '322'}];
const result = countries.map((country) => ({
...country,
visible: countryVisible.includes(country.name),
}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Solution 2:[2]
There are minor issues with your code; two issues (maybe 3):
- You do not have a
return el2;in themapmethod - You do not assign the result back to
countries, and hence, - The variable
countriesshould be declared with alet
And then, there's a major issue:
- Since you're setting the state of
visiblebased oncountryVisiblearray instead of based on the country object being considered, a visible state can be set tofalseeven though it was set totruethe first time. Eg.EUAwill be set tofalsein the final result. - In other words instead of checking and setting each country object just once, each is checked as many times as there are country objects.
const countryVisible = ['EUA', 'CANADA'];
let countries = [{name: 'EUA', id: '123'}, {name: 'CANADA', id: '321'}, {name: 'Italia', id: '322'}];
countries = countries.map((el2, index2) => {
if( countryVisible.includes( el2['name'] ) ) {
el2 = {...el2, visible: true};;
} else {
el2 = {...el2, visible: false};;
}
return el2;
});
console.log(countries);
A better approach:
Consider using map and just adding the visible property to the mapped element.
const countryVisible = ['EUA', 'CANADA'];
const countries = [{name: 'EUA', id: '123'}, {name: 'CANADA', id: '321'}, {name: 'Italia', id: '322'}];
const output = countries.map(
({name,id}) =>
({name,id,visible:countryVisible.includes(name)})
);
console.log( output );
Solution 3:[3]
You can use this syntax to assign conditional property to JS object. (ES6)
const a = {
...(someCondition && {b: 5})
}
Or you can use Javascript Object.defineProperty built-in function
Object.defineProperty(obj, 'foo', {
value: 1
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | A1exandr Belan |
| Solution 2 | |
| Solution 3 | nillabobillababolla |
