Skip to content

How to update a key/value pair in a nested array of objects in Javascript

this is my data structure:

[
    0:
        key1: value,
        key2: value,
        array:
            0:
                thisId: xxxxx,
                thisValue: value,
            1:
                notThisId: someId,
                notThisValue: value,
        key3: value
    1:
        key1: value
        key2: value
        array:
            0:
                anotherId: id
                anotherValue: value
        key3: value
]

Hello, I have a query with is returning:

thisIdRef: xxxxx, 
thisNewValue: newValue

Is it possible to update the nested ‘thisValue’ to ‘thisNewValue’ where ‘thisIdRef’ is equal to ‘thisId’, or ‘xxxxx’?

I have done something similar below using findIndex and splice, but this is for a non-nested key/value pair and I can’t work out how to find a nested id, or indeed if it’s possible.

let newArray = oldArray;
const index = newArray.findIndex(post => post._id === editedPostId)
newArray.splice(index, 1, {
    ...newArray[index],
    post: editedContent
})

Any help very much appreciated.

Answer

I will assume you want to create a new array, such that the original array and its nested structure is not mutated.

Here is a function that you could use:

function setDeep(original, editedPostId, editedContent) {
    return original.map(obj => {
        let i = obj.array.findIndex(item => item.thisId === editedPostId);
        if (i == -1) return obj;
        return {
            ...obj, 
            array: Object.assign([], obj.array, { 
                [i]: {
                    ...obj.array[i], 
                    thisId: editedPostId, 
                    thisValue: editedContent 
                }
            })
        }; 
    });
}

// Example call
let original = [{
    key1: 1,
    key2: 2,
    array: [{
        thisId: "xxxxx",
        thisValue: 3,
    }, {
        notThisId: "yyyy",
        notThisValue: 4,
    }],
    key3: 5
}, { 
    key1: 6, 
    key2: 7,
    array: [{
        anotherId: "zzzzz",
        anotherValue: 8
    }],
    key3: 9
}];

let editedPostId = "xxxxx";
let editedContent = 42;

console.log(setDeep(original, editedPostId, editedContent));

Note that the code you have given for a non-nested structure seems to create a new array, but it still mutates the original array. When you want the original to remain in tact, you have to take care to deep-copy the parts that are affected.