ramos97
ramos97

Reputation: 35

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
    }
]

Upvotes: 1

Views: 168

Answers (3)

PeterKA
PeterKA

Reputation: 24638

There are minor issues with your code; two issues (maybe 3):

  • You do not have a return el2; in the map method
  • You do not assign the result back to countries, and hence,
  • The variable countries should be declared with a let

And then, there's a major issue:

  • Since you're setting the state of visible based on countryVisible array instead of based on the country object being considered, a visible state can be set to false even though it was set to true the first time. Eg. EUA will be set to false in 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 );

Upvotes: 3

A1exandr Belan
A1exandr Belan

Reputation: 4780

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

Upvotes: 1

nillabobillababolla
nillabobillababolla

Reputation: 44

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

Upvotes: 0

Related Questions