0

My question relates to this one but the issue here that I must relay on object properties and I want to update just ONE object. If I am using map it updates all objects in my array of objects. Its structure is:

[
    {
      id: 1,
      itemNames: ['aaa','xxx'],
      removed: [],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy', 'xxx'],
      removed: [],
      ...
    },
    ...
]

My logic is: I look for item name across itemNames, if it exists in state - remove it from first object occurance and add it to removed property of this object. I managed to do it with map, but then it does it for every object that has given item name.

function filterByItemName(itemName) {
  this.setState(prevState => ({
    ...prevState,
    arr: prevState.arr.map(item) => {
      if (item.itemNames.includes(itemName)) {
        return {
          ...item,
          removed: [...item.removed, itemName],
          itemNames: removeFirstFoundElement(item.itemNames, itemName),
        };
      }
      return item;
    }),
  }));
}

The following code works in a way that it finds ALL objects with given itemName - but I would like to change just first case... After calling filterByItemName('xxx') I want it to be:

[
    {
      id: 1,
      itemNames: ['aaa'],
      removed: ['xxx],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy', 'xxx'],
      removed: [],
      ...
    },
    ...
]

While now it is as follows:

[
    {
      id: 1,
      itemNames: ['aaa'],
      removed: ['xxx],
      ...
    },
    {
      id: 1,
      itemNames: ['yyy'],
      removed: ['xxx'],
      ...
    },
    ...
]
3
  • Please create a small demo for this using codesandbox.io to show the issue happening. Commented May 5, 2020 at 8:57
  • 1
    Everything is there - how it works now and how it should as well... Commented May 5, 2020 at 9:03
  • Trying to understand what you're trying to do - you want to remove the first found element and update all the other matching ones? Commented May 5, 2020 at 9:13

1 Answer 1

0

I think you can set a shouldInsert flag to check if you've already inserted once or not. Here is my approach. It would be easier if you could share some codesandbox link here.

function filterByItemName(itemName) {
  let shouldInsert = true;
  this.setState(prevState => ({
    ...prevState,
    arr: prevState.arr.map(item) => {
      const found = item.itemNames.includes(itemName);
      if (found && shouldInsert) {
        shouldInsert = false;
        return {
          ...item,
          removed: [...item.removed, itemName],
          itemNames: removeFirstFoundElement(item.itemNames, itemName),
        };
      }
      return item;
    }),
  }));
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.