1

I have a player object with sub property type:

'player': {
            'count': 11,
            'type': 'forward'
}

Now i would like to call setPlayer( {...playerDetails, [key]: e.target.value}) to keep the existing player object and only change one property (i.e. player.type).

Using [key]: e.target.value works fine with changing root level property like player , but how can i use key to set the sub level property player.type.

['player.type']: e.target.value will only create a 'player.type' string property in root level but not override nor create sub-level property 'type' in player.

Barmar
  • 741,623
  • 53
  • 500
  • 612
instantlink
  • 180
  • 1
  • 9

1 Answers1

1

I think what you are asking for is:

const [key1, key2] = "player.type".split('.')
const playerDetails = {foo: 'bar'}, e = {target: {value: 12}}
const res = {...playerDetails, [key1]: {...playerDetails[key1] ?? {}, [key2]: e.target.value} }
console.log(res)

This approach is not feasible for more than two levels, though it works in a recursive algorithm too:

const data = {foo: 'bar', player: {name: 'baz'}}
const prop = "player.value.default"
const setProp = (obj, [prop, ...path], value) => !prop ? value : {...obj, [prop]: setProp(obj[prop] ?? {}, path, value)}
console.log(setProp(data, prop.split('.'), 42))
But there are more efficient ways to do it.
Moritz Ringler
  • 9,772
  • 9
  • 21
  • 34
  • what is key2 doing? i am passing key='player.type' and want it to create player: {type: someValue } – instantlink Feb 06 '23 at 23:50
  • @instantlink In your example it says `player.type`, which I understood as `player` being key1 and `type` being key2. – Moritz Ringler Feb 06 '23 at 23:55
  • @instantlink I think it is clearer now. This stuck with me a bit lol. Good question! – Moritz Ringler Feb 07 '23 at 01:17
  • i had same idea of splitting the key but was asking if there was any trick to do it easier since it seems to be a quite common task to do – instantlink Feb 07 '23 at 10:51
  • @instantlink Oh, it reads like you asked "how to use key to set the sub level property", i.e. how to use destructuring on a deeper level than just the first. – Moritz Ringler Feb 07 '23 at 11:00
  • your sample works fine for up to level 2. Thanks for pointing out to the recursive solution! Yet i was looking for a more generic approach in this topic (need it up to level 3). Seems ['player.type'] will always result in "player.type" and not "player: { type: ...." – instantlink Feb 07 '23 at 11:13
  • @instantlink Not sure what you mean, the two level statement gives you `"player: { type: ....` and the function resolves it for any level. Made the first one a snipped to be sure and it works as expected. Anyway, that was fun, cheers – Moritz Ringler Feb 07 '23 at 11:23