1

I have array of objects and the format is like this

 addedOpaqueMaterials = [{
            conductivity: 1
            density: 1
            id: "1"
            ......
            ......
         },
         {
             conductivity: 2
             density: 1
             id: "2",
             ......
             ......
         }]

and from the react state i am getting updated object with the id= 2 like as this below,

{
    conductivity: 4
    density: 23
    id: "2",
    ......
    ......
}

and i am looking to update the object in main array with these values, what could be the best way to update, below is the code related to that.

const handleDrawerSubmit = values => {
   const addedOpaqueMaterials = formValues.constructionSet?.opaqueMaterials; // array of objects

   const updatedMaterial = addedOpaqueMaterials.find(i => i.id === values?.opaqueMaterial?.id);
   // values?.opaqueMaterial is having updated object
    
   // Object.assign(updatedMaterial, values.opaqueMaterial); getting an error      
};

Now I would like to merge values.Opaquematerial object into addedOpaqueMaterials which is array of objects, what could be the best way to achieve this?

Many thanks

2

2 Answers 2

2

This is just a regular algorithm challenge. No need to otherthink it. The only requirement that react demands out of you is that it needs to be a new array. Array#map works perfectly fine.

const materialExists = addedOpaqueMaterials.some(({id}) => id === values?.opaqueMaterial?.id)
let updatedMaterial
if (materialExists) {
    updatedMaterial = addedOpaqueMaterials.map(material => {
        if (material.id === values?.opaqueMaterial?.id) {
            return values.opaqueMaterial
        }
        return material
    })
} else {
    updatedMaterial = [...addedOpaqueMaterials, values.opaqueMaterial]
}
Sign up to request clarification or add additional context in comments.

Comments

1

Instead of using .find, use .findIndex first, so that you can replace the object in the array with the new object. (Remember not to use Object.assign in React when the first parameter is stateful, because that'd result in a state mutation)

You should also check that all of these objects exist first before trying to update.

if (!formValues.constructionSet || !values || !values.opaqueMaterial) {
  return;
}
const newMat = values.opaqueMaterial;
const index = addedOpaqueMaterials.findIndex(mat => mat.id === newMat.id);
if (index === -1) {
  // Add to the end of the existing array:
  const newOpaqueMaterials = [
    ...addedOpaqueMaterials,
    newMat
  ];
  // put newOpaqueMaterials into state
} else {
  // Replace the object in the state array with the new object:
  const newOpaqueMaterials = [
    ...addedOpaqueMaterials.slice(0, index),
    newMat,
    ...addedOpaqueMaterials.slice(index + 1)
  ];
  // put newOpaqueMaterials into state
}

4 Comments

You should modify your variable declarations. Declaring inside the if block will make the array unavailable where it's needed. EDIT: Sorry, I did not see your comment. Seems kind of weird, to have the same operation in an if and else, but it is viable.
@Andrew OP didn't show how he's updating the state, or if he's using hooks or class components. He'll probably be able to replace the occurrences of // put newOpaqueMaterials into state with setMaterials(newOpaqueMaterials) or the equivalent, which doesn't require modifying the scope used in the answer.
The construction of the new array is somewhat different depending on whether the index is -1 or not. Yeah, I guess you could use the conditional operator to shove it all into a single statement (or use let, ew), but I really think separate blocks makes the intent of the code clearer.
Using let from time to time isn't the worst thing in the world. Another option is a do expression, but that would only be an answer if you assume they have the babel config for it.

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.