davidgilbertson/react-recollect

Approach to updating deeply nested data?

Closed this issue · 2 comments

deep references to items in the store may be broken if you modify the store. I'd be interested to hear about cases where this is proving unpleasant. Please feel free to open an issue with a code snippet, even if you think it's something that can't be fixed.

Me! So, I have an object tree like: store.devices[id].services[id].something

I have to, because of possible null/undefined values, check to see that the particular item exists when doing an update operation.

Right now, I am doing something kinda ugly:

// not actual code, but similar

if (!store.devices[dID]) throw new Error('No device!')
if (!store.devices[dID].services || !store.devices[dID].services) throw new Error('No services!')
if (!store.devices[dID].services[sID]) throw new Error('No service!')

store.devices[dID].services[sID].foo = true
await something()
store.devices[dID].services[sID].foo = false

Is there a better way to do this?

What if my object was store.devices[dID].services[sID].foo[a].bar[b].baz = true?

Hmm, good question. So you're saying the problem is the length/messiness of these lines?
You could use Lodash get(), which will retrieve a deeply nested property.

if (!get(store, `devices.${dID}.services.${sID}`)) throw new Error('No services!')

Or create your own/wrap the Lodash get, like:

const hasService = (store, dID, sID) => !!get(store, `devices.${dID}.services.${sID}`);

If you want to dynamically create a path for a device/service combination, Lodash set() does that, so this is safe, even if the store is empty:

set(store, `devices.${dID}.services.${sID}.someProp`, true)

Sorry again for the tardy replies!

@davidgilbertson thanks, using a helper makes sense. I wanted to first make sure I wasn't missing something obvious. I actually, after writing this, created a helper of sorts to do this, but using Lodash get is more elegant.

I think this will confuse most new users, so may be good to instruct people to this technique in the readme?