Properties assigned undefined when accessing them for the first time
rubixibuc opened this issue · 1 comments
Hi!
I'm creating a property definition similarly matching the following
localStorageBackProperty: {
get: () =>
localStorage.getItem("localStorageBackProperty") &&
new Date(localStorage.getItem("localStorageBackProperty")),
set: (host, value) => {
localStorage.setItem("localStorageBackProperty", value + "")
}
}
What I'm seeing is that simply reading the variable host.localStorageBackProperty
is for some reason passing undefined
to the property setter, erasing the value that was in localStorage
Is this expected?
hybrids version: 7.1.0
The get
and set
method of the property definition works similarly to the getter/setter from the Object.defineProperty()
function.
The set
method is additionally called, if the value is not defined, as you may want to compute the value only by defining the set method - https://github.com/hybridsjs/hybrids/blob/v7.1.0/src/define.js#L179 - without defining the get
- then the set
is called also for the first access of the property.
In simpler words, the set
method should always return a value, which is passed to get
, as a lastValue
when property is accessed. Your code example does not return a value in set
method.
However, in general, you should use store
factory in your case, as you try to combine an external source with a simple get
/ set
method - in which a source is an internal cache of the component itself.
It would not be that complicated:
import { store } from "hybrids";
const Data = {
back: "",
[store.connect]: {
get: () => JSON.parse(localStorage.getItem("myData")) || {},
set: (_, data) => {
localStorage.setItem("myData", JSON.stringify(data));
return data;
},
}
};
// component
{
data: store(Data),
// or
back: () => store.get(Data).back,
}
// updating the value
store.set(data, { back: ... });
The above example uses a dictionary of keys, rather then a single value, but it is easy to refactor it to work that way.
You can also take out the [store.connect]
definition to the storage factory function, like [store.connect]: localStorage("myKey")
if there are more models like this, and use it:
const Options = {
...,
[store.connect]: localStorage("options"),
};