How to remove ONE item if there are two items having the same value in array of objects in JavaScript?

Viewed 101

So I have this array of objects of cards which I'm displaying in vuejs.

cardsFromBackEnd: [
  {
    id: 1,
    tickerName: 'IBM',
    tickerFullName: 'International Business Machines',
    benchMark: 121.3,
    totalReturn: 16.9,
    tradeReturn: -14.0,
    sharpeRatio: 0.0006,
    winRate: 28.2,
    date: 'Mon Oct 31',
    tags: ['IBM'],
  },
  {
    id: 2,
    tickerName: 'HP',
    tickerFullName: 'Hawlett-Packard',
    benchMark: 91.3,
    totalReturn: 10.9,
    tradeReturn: 23.2,
    sharpeRatio: 0.0006,
    winRate: 68.2,
    date: 'Sun Oct 30',
    tags: ['IBM'],
  },
  {
    id: 3,
    tickerName: 'Appl',
    tickerFullName: 'Apple',
    benchMark: 201.3,
    totalReturn: 110.9,
    tradeReturn: 173.2,
    sharpeRatio: 0.0006,
    winRate: 168.2,
    date: 'Sat Oct 29',
    tags: [],
  },
],

I'm showing tags on the bottom left corner which are saved in tags array.

the tags also have a remove button. when there are different tags in cards, only that tag is deleted which is clicked. But my issue is that if there is a tag which has the same value in both cards get clicked for removal, that tag is removed from both cards.

here is the html of tags

<vs-chip
  v-for="tag in cardData.tags"
  :key="tag.id"
  @click="remove(tag)"
  closable
  close-icon="delete"
  >
  {{ tag }}
</vs-chip>

and here is the click event

remove(tag) {
  eventBus.$emit('delTag', tag);
},

and here is the listener for that remove method

// Deleting tag on clicked card
eventBus.$on('delTag', (tag) => {
    let cardTags = this.cardDetails.filter((card) => {
    if (card.tags.includes(tag)) {
      card.tags.splice(card.tags.indexOf(tag), 1);
    }
  });
});

Is there a way to tell that only delete that tag from the card on which it was clicked for removal?

Thank you.

2 Answers

Pass both the card and tag to your remove() method and event

<vs-chip
  v-for="tag in cardData.tags"
  :key="tag.id"
  @click="remove(cardData, tag)"
  closable
  close-icon="delete"
  >
  {{ tag }}
</vs-chip>
remove(card, tag) {
  eventBus.$emit('delTag', { card, tag })
},
eventBus.$on('delTag', ({ card, tag }) => {
  card.tags = card.tags.filter(cardTag => cardTag !== tag)

  // or

  card.tags.splice(card.tags.indexOf(tag), 1)
})

You will need to pass the id of the clicked card to your function and do something like this, and you don't need to use filter in your case.

let cardTags = getCardTags(theOnClickedCardId)

function getCardTags(theOnClickedCardId){
return this.cardDetails.map((card) => {
   if (card.tags.includes(tag) && card.id == theOnClickedCardId) {
     card.tags.splice(card.tags.indexOf(tag), 1);
   }
})};
Related