Pietro Lungarini
Pietro Lungarini

Reputation: 181

Javascript Array doesn't map correctly

I'm "consolling" the entire code... but I can't find any issue, only a weird behaviour.

Let me explain: I've an angular component (let's call it parent) which send some tags to his child through a inputTags array. Then I need to set another list with ALL the tags of the user, called allTags.

The array (both inputTags and allTags) is formatted like this: { id: 'tagId', name: 'tagName' }

I need to make an unified array of those two. The expected output should contain an array of items that it's formatted like this: { id: 'tagId', name: 'tagName', selected: boolean }

In order to do this I'm mapping the allTags array in this way:

Let's suppose that:

inputTags = [
    { id: 'work', name: 'Work' },
    { id: 'motivation', name: 'Motivation' }
];

allTags = [
    { id: 'network', name: 'Network' },
    { id: 'work', name: 'Work' },
    { id: 'smart', name: 'Smart' },
    { id: 'motivation', name: 'Motivation' }
];

Now... allTags are actually retrived from a server, so my code looks something like this:

this.tagsService.getAll().subscribe(tags => {

    this.allTags = tags.map(tag => {
        let select = false;
        this.inputTags.forEach(inputTag => { select = (inputTag.id === tag.id) })
        return {
          id: tag.id,
          name: tag.name,
          selected: select,
        };      
    });

})

This for me seems quite standard, but in fact NO, because instead of getting:

allTags = [
    { id: 'network', name: 'Network', selected: false },
    { id: 'work', name: 'Work', selected: true }, // is selected
    { id: 'smart', name: 'Smart', selected: false },
    { id: 'motivation', name: 'Motivation', selected: true } // is selected
];

I get this:

allTags = [
    { id: 'network', name: 'Network', selected: false },
    { id: 'work', name: 'Work', selected: false }, // is NOT selected
    { id: 'smart', name: 'Smart', selected: false },
    { id: 'motivation', name: 'Motivation', selected: true } // is selected
];

Basically the issue is that it's selecting only one tag, not multiple tags.

Upvotes: 0

Views: 81

Answers (3)

Santi Barbat
Santi Barbat

Reputation: 2295

Try the following:

this.allTags = allTags.map(tag => ({
  id: tag.id,
  name: tag.name,
  selected: inputTags.some(i => i.id === tag.id),
}))

Upvotes: 0

Amadou Beye
Amadou Beye

Reputation: 2808

You can try some:

this.allTags = tags.map(tag => {
    return {
      id: tag.id,
      name: tag.name,
      selected: this.inputTags.some(inputTag => inputTag.id === tag.id)
    };      
});

Upvotes: 1

Kavinda Senarathne
Kavinda Senarathne

Reputation: 2004

JavaScript Array map() Method

*)creates a new array with the results of calling a function for every array element and it calls the provided function once for each element in an array, in order.

Note: map() Method does not execute the function for array elements without values and it does not change the original array.

Upvotes: 0

Related Questions