Intended outcome:
function-properties in observable objects are expected to be enumerable
Actual outcome:
function-properties are gone when iterating an observable object
How to reproduce the issue:
I created this example: https://codesandbox.io/s/jovial-black-rq0pw?file=/src/index.ts
The onMore-prop is actually not contained when calling Object.keys(x.notification) since functions are not enumerable in observable objects. I am coming from mobx 4 and this used to work and now it breaks my app in some cases, since I use spreading to pass observable-objects to components like <Component {...notification} />
Versions
Mobx 6
We may change it so that enumerability is respected, but I can't give you a promise atm, it's being discussed/worked on.
Related #2586
For the time being as a workaround try:
const obj = {
text: "abc",
onMore: action(() => {})
};
Or
const obj = observable({
text: "abc",
onMore: () => {},
}, {
onMore: false
});
Please note that spreading observable objects into components as props is an anti pattern: https://mobx.js.org/react-integration.html#tip-grab-values-from-objects-as-late-as-possible. The idiomatic way to pass the notification down is <Component notification={notification} />, while making sure <Component> is an observer.
If you can't make Component observer because it is not under your control, I recommend pass down properties down explicitly. Especially with actions you probably want to do that anyway to make sure callbacks are invoked by with the right context (<Component title={notification.title} onSetTitle={(title) => notication.onSetTitle(title)} /> rather than <Component {...notification} /> which will break if notification.onSetTitle wasn't bound)
It seems very unexpected that properties may suddenly be removed from an object when enumerating, especially since imo mobx' power has always been that it makes you interact with the observables like they are native object/maps/arrays etc (with a little magic when you wrap them into observers).
I can see how it is an anti-pattern but I've been using it mostly in tests and stories to quickly create a set of observable values that I then spread into a react component. When I upgraded to MobX 6 many of these stories broke. There might be tons of more use-cases but I think most important is that its just very DX unfriendly .