1

I have an object that contain a property with an array of objects which I have to change one object.

{id: '3688aa8f-e725-45f4-9513-363a1c019b34',
 category: 'Entertainment: Film',
 difficulty: 'easy',
 question: "What is the orange and white bot's name in "Star Wars: The Force Awakens"?",
  answers: [ 
    {id: 'da42762a-e936-42d8-ae61-2a0de53d3c5e', incorrect_answer: 'Austria', isSelected: false}, 
    {id: '44d8549f-31a7-4cdd-8a6b-80cf6a1b853c', incorrect_answer: 'Armenia', isSelected: false},
    {id: '2f734291-b4cf-48a0-8e54-3379b7d23ecb', incorrect_answer: 'Australia', isSelected: false},
    {id: 'dfa6fa70-3b44-44fe-b80a-fc9da72a6c7f', incorrect_answer: 'Afghanistan', isSelected: false}
   ]
} 

How can I iterate over the answers array and change the property isSelected to true?

I am trying to use the spread operator, but its not working.

5
  • Maybe use find to find the object using the id in the condition, and then update the other value? Commented Jan 2, 2023 at 18:40
  • How are you trying the spread operator? Commented Jan 2, 2023 at 18:42
  • try yourObj.answers.forEach(e => e.isSelected = true) Commented Jan 2, 2023 at 18:42
  • 1
    Is this stored in react state? Because if so, the above comments would break the rules of react in regards to immutability. Commented Jan 2, 2023 at 18:52
  • @lharby map return value must be the whole item object and not only e.isSelected = true Commented Jan 2, 2023 at 18:52

2 Answers 2

0

Since your post is tagged with React, it's additionally important (if this object is contained within React state) to do this in a way that does not mutate the original structure, but instead, creates a new structure with the desired edit.

For the sake of example, I'm going to assume it's stored in some react state I've called obj.

const setAnswerIsSelected = (idToChange, isSelected) => {
    setObj(prevObj => ({
        ...prevObj,
        answers: [
          { ...prevObj.find(({id}) => id === idToChange), isSelected },
          ...prevObj.filter(({id}) => id !== idToChange) 
        ]
    }))

}

Just getting the answer object itself and mutating it is not a good idea if this is in React state as doing so is not allowed in React.

Deep updates can be cumbersome. Changing the state structure to be flatter and spread across multiple items can alleviate this. Or use something like Immer.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Adsy for the advice. Actually the data is more cumbersome than this because which object of data like is inside of another array. I will take your advice and change the state structure.
0

Spread Operator Solution

as @adsy mentioned with this solution you will lose the object reference to the answers item if its used somewhere else in your app. The spread operator will create a new object of the array item.

const obj = {id: '3688aa8f-e725-45f4-9513-363a1c019b34',
 category: 'Entertainment: Film',
 difficulty: 'easy',
 question: "What is the orange and white bot's name in "Star Wars: The Force Awakens"?",
  answers: [ 
    {id: 'da42762a-e936-42d8-ae61-2a0de53d3c5e', incorrect_answer: 'Austria', isSelected: false}, 
    {id: '44d8549f-31a7-4cdd-8a6b-80cf6a1b853c', incorrect_answer: 'Armenia', isSelected: false},
    {id: '2f734291-b4cf-48a0-8e54-3379b7d23ecb', incorrect_answer: 'Australia', isSelected: false},
    {id: 'dfa6fa70-3b44-44fe-b80a-fc9da72a6c7f', incorrect_answer: 'Afghanistan', isSelected: false}
   ]
};

obj.answers = obj.answers.map(e => ({...e, isSelected: true}));
console.log(obj.answers);

forEach Solution

const obj = {id: '3688aa8f-e725-45f4-9513-363a1c019b34',
 category: 'Entertainment: Film',
 difficulty: 'easy',
 question: "What is the orange and white bot's name in "Star Wars: The Force Awakens"?",
  answers: [ 
    {id: 'da42762a-e936-42d8-ae61-2a0de53d3c5e', incorrect_answer: 'Austria', isSelected: false}, 
    {id: '44d8549f-31a7-4cdd-8a6b-80cf6a1b853c', incorrect_answer: 'Armenia', isSelected: false},
    {id: '2f734291-b4cf-48a0-8e54-3379b7d23ecb', incorrect_answer: 'Australia', isSelected: false},
    {id: 'dfa6fa70-3b44-44fe-b80a-fc9da72a6c7f', incorrect_answer: 'Afghanistan', isSelected: false}
   ]
};

obj.answers.forEach(e => e.isSelected = true);
console.log(obj.answers);

1 Comment

I think this is still potentially problematic as answers is still mutated. Though the way of mapping over it is cleaner than mine. If you adopt my approach but also use your use of map it'd be the best answer :).

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.