Creating new nested key
AshMartian opened this issue · 2 comments
I have a settings local-storage model with nested attributes. This is working great, but when trying to add more attributes I'm confused as to why the ember-local-storage plugin isn't simply creating the new key for the missing nested attribute. For example:
My settings when project was first launched in the browser:
lastWifi: false,
lastConnected: null,
settings: {
language: 'en',
about: {
version: "0.5"
}
}
This created a localStorage object, works like a charm. However in developing the app, I need to add more nested keys.
lastWifi: false,
lastConnected: null,
settings: {
language: 'en',
about: {
version: "0.5"
},
bluetooth: {
allow: true
}
When trying to access the bluetooth and it's allow key, I'm getting this error:
ember.debug.js:19818 Property set failed: object in path "settings.bluetooth" could not be found or was destroyed.
Error
at setPath (http://localhost:4200/assets/vendor.js:35584:15)
at Object.set (http://localhost:4200/assets/vendor.js:35504:14)
at Class.set (http://localhost:4200/assets/vendor.js:48371:26)
at Class.saveIfChanged (http://localhost:4200/assets/vendor.js:74170:17)
at Class.superWrapper [as set] (http://localhost:4200/assets/vendor.js:54095:22)
at Class.toggleSetting (http://localhost:4200/assets/www.js:1207:30)
at Backburner.join (http://localhost:4200/assets/vendor.js:13883:21)
at Function.run.join (http://localhost:4200/assets/vendor.js:35754:28)
at http://localhost:4200/assets/vendor.js:23468:37
at Object.flaggedInstrument (http://localhost:4200/assets/vendor.js:31850:14)
I understand I could use the .isInitialContent()
.clear()
or .reset()
functions, however I would then have to do this for every update I deploy or on every new key I add? Seems somewhat counter productive and could lead to a bad user experience.
I've now added my local-storage to a model, as recommended for nested attributes. However the behavior does not change.
@blandman Thanks for the feedback. I get your point. The problem is that the addon only sets the initial state if there is no data for that key. It seem that your problem is a common scenario for nested objects. I see different approaches how we can handle it.
First of all you should be able to solve it like that:
// Setup the new key
if (!this.get('settings.bluetooth')) {
this.set('settings.bluetooth', {});
}
this.set('settings.bluetooth.allow', true);
We could now add that functionality in some way or another to the addon but I'm not sure yet how to not impact the performance for all storage objects. I think one way might be an option on the storageFor
to tell it that there needs to be some migration work to be done (storageFor('settings', { migrate: true })
). It should just check for new keys in initialState
and add that defaults.
Another way would be to add a new method setWithDefault('settings.bluetooth.allow', true, {})
that would do the setup for the new key (like in the code example above).
What do you think is the best way? Do you have a better idea?
Thank you so much for this! I could test performance, the app I'm working on has a lot of realtime data and ideally has many user configurable settings and running on mobile. Having migrate as a storageFor option is brilliant. The basic functionality would go a long way.
I could quickly test a few options 👍