Tom el Safadi
Tom el Safadi

Reputation: 6796

Replace Nested Object with Map

I am trying to replace a nested object with an updated object with map. However, it only works if I replace each property but I cannot replace the entire object with the updated one. The following is my strucutre:

[
    {
        name: 'Parent 1',
        data: [
            {
                id: 1,
                name: 'Child 1', 
                // more properties ...,
            },
            {
                id: 2,
                name: 'Child 2', 
                // more properties ...
            }
        ]
    }
]

Now I want to replace a child in its parent with an updated child. This is what I have right now and it works but it isn't maintainable to map each property manually:

    parents.map(parent =>
        parent.data.map(child => {
            if (child.id === newChild.id) {
                child.name = newChild.name;
                // more mappings ...
            }
        })
    );

This is what doesn't work but the solution I would prefer:

    parents.map(parent =>
        parent.data.map(child => {
            if (child.id === newChild.id) {
                child= newChild;
            }
        })
    );

I am also open to other solutions rather than using map. I am not sure if this is the correct way of doing it.

Upvotes: 1

Views: 920

Answers (2)

this is your original script, I just add the index of the data array to the map and changed the way to assign the value to child. At this case I assign the newChild to parent.data[index]. This is the code:

parents.map((parent) =>
    parent.data.map((child, itemChild) => {
        if (child.id === newChild.id) {
            parent.data[itemChild] = newChild;
        }
    })
);

Upvotes: 0

a.mola
a.mola

Reputation: 4011

I don't know where the newChild is coming from, but...

If you want to replace that whole child, you have to use its index. Like so,

parents.forEach(parent => parent.data.forEach((child, index) => {
    if (child.id == newChild.id) child.data[index] = newChild;
}));

If not , you are just changing the value of the variable child in that loop.

I changed the map to forEach since I assume you want to edit the original array. Use this

parents = parents.map(parent => parent.data.map((child, index) => (child.id == newChild.id) ? newChild : child));

This way, the new child will take this space of the old one in the map if their ids match else the old child will still be returned

Upvotes: 1

Related Questions