This https://stackoverflow.com/a/4255480/1375882is good answer about the use of bracked notation to access the properties of the Javascript object/array by the name and it also show examples how to access nested properties or elements from the nested arrays.

I am trying to use the same approach to access the properties/elements in the construction that uses spread ... operator, e.g.:

var foo = { a: 1, b: 2, c: {x: 999, y:998, z: 997}};
var foo1 = {...foo,
               ['a']: 2,
               ['c']['y']: 1000,
            };

alert(foo1['c']['y']);

But this code does not compile - while the one-level access ['a'] works as expected, the nested access ['c']['y'] does not work with with spread (but it works outside spread) - the code simply does not compile, there are error messages about un-matched { and other obscure messages (e.g. in jsfiddle).

My question is - how to access nested properties/elements within spread? Maybe other constructions that brackets are necessary?

Context: I am trying to write general code that listend to the cell value changes in the AgGrid and accordingly updates the Redux store: grid displays the array or records and in my update code I should find the right record and the right cell within it - all this happens in Redux reduce with usually uses spread... for correct update of state, e.g. idiomatic code is:

case GET_INVOICES_SUCCESS: {
              return {...state,
                 invoiceDate: action.response.data.invoiceDate,
              }
            }

But I should be able to access the individual properties and nested propertes of the state here. This agGrid in react + redux app is modifying underlying data is the code which I am trying to generalize.

So - you can see that the use of spread... is not luxury for me, it is the best practice for use in Redux reducers and that is why I have this question.

3

There are 3 answers

1
TomR On BEST ANSWER

Thanks Tasos and Nina for suggestions, but I specifically asked for the case when property is accessed by name and that is why the correct answer is this:

var foo = { a: 1, b: 2, c: {x: 999, y:998, z: {aa: 5, bb: 6}}};
var foo1 = {...foo,
               ['a']: 2,
               ['c']: {...foo['c'], 
                    ['y']: 1000, 
               },
               ['c']: {...foo['c'],
                    ['z']: {...foo['c']['z'],
                          ['bb']: 777,
                           }
               }
            };

alert(foo1['c']['z']['bb']);

I don't know whether I should accept my own answer because without input from the previous answer there would not be my answer.

0
Nina Scholz On

You could separate the wanted nested property with an own spreading.

const
    foo = { a: 1, b: 2, c: { x: 999, y: 998, z: 997 } },
    foo1 = { ...foo,
        a: 2,
        c: { ...foo.c, y: 1000 },
    };

console.log(foo1['c']['y']);
console.log(foo1);

0
Tasos On

You should use the spread operator for the nested properties as well:

var foo = { a: 1, b: 2, c: {x: 999, y:998, z: 997}};
var foo1 = {...foo,
               a: 2,
               c: { ...foo.c, y: 1000 },
            };

alert(foo1.c.y);

Also, you don't need the square brackets if the property name is not a variable.