ngrx-store-localstorage
ngrx-store-localstorage copied to clipboard
Primitive values are unserialized to strings
My state looks like:
{
"name": "John",
"age": 12,
"married": false,
"children": []
}
And I use the metareducer as below:
localStorageSync({
keys: ['name', 'age', 'married'],
rehydrate: true
})(reducer)
It causes issues because it will create three different entries in the localStorage with the respective values "John"
, "12"
and "false"
. During unserialization, these entries will remain strings as they are not parsed using JSON.parse
(because they are not object-like values) and will equal "12"
(I mean "12"
as a string).
A possible alternative is to avoid storing primitive values, but it is quiet hard to keep in mind and does not look to be a bad practice (as I could not find any article about this topic). Another solution would be to always store states as objects instead of values. Another benefit would be to avoid multiplication of entries in the localStorage (one entry per state instead of one per key). The result in the localStorage would look like:
{"name":"John","age":12,"married":false}
Such a change would have incident on the way serialization is done and the main consequences would be:
- the given
keys
property would only filter on the properties we want to keep during serialization - a name should be given to the
LocalStorageConfig
, corresponding to the feature name or theroot
.
I can create a PR if this suggestion looks viable to you and is wanted for the future.
Any update regarding this issue?
You could pass a reviver
function that parses the non-string keys.
Assuming that the state slice is called person
, it should be something like this:
const personReviver = (key, value) => {
switch (key) {
case 'age':
return Number(value);
case 'married':
return !!!value;
default:
return value;
}
};
localStorageSync({ keys: [{ person: { reviver: personReviver } }], rehydrate: true })(reducer);
You can try the following:
localStorageSync({
keys: ['name', { age: { deserialize: parseInt } }, 'married'],
rehydrate: true
})(reducer)