Welcome to MobX. Please provide as much relevant information as possible!
I have a:
Please tick the appropriate boxes. Feel free to remove the _other_ sections.
Please be sure to close your issues promptly.
error 'set' on proxy: trap returned falsish for property 'Symbol(count)' threw when using Symbol as key in an observable,
Addition, if using mobx@4, it just fails silently rather than throwing the error out in version 5.
I fail to understand the use-case of this scenario, you want to create a dynamic key?
isn't it what extendObservable does?
ref: https://mobx.js.org/refguide/extend-observable.html
Hi @ItamarShDev,
The question is mobx doesn't work when using a Symbol as an object key.
// works
observable({
count: 0,
})
// broken
observable({
Symbol('count'): 0,
})
I am maintaining a vue.js project, and bring mobx to do state management rather than the native vue way. The original practice of this project using sth like Symbol('isSelected') as an observable object key, and it works now, but fails in mobx. So I am curious about the difference caused by my misuse of mobx or mobx doesn't support it.
Thanks for the explanation @kimochg !
This is an interesting problem.
If Symbols where supported, could it conflict with current or future well-known symbols like: Symbol.iterator, Symbol.toStringTag, etc. ?
Should there be a list of excluded symbols ?
Disclaimer: I am currently taking advantage of the fact that symbols are ignored by MobX in my MobX extension library: https://github.com/jlgrall/mobx-patch-computedTree, but I can find another way.
Mobx ignores non-enumerable props (like symbols) in observable/extendObservable.
The symbol is firstly introduced to the observable object during the assignment (in incSymbol).
Mobx4 doesn't support dynamic keys, so the standard JS behavior (new non-observable property is added to object) takes place, therefore no error.
In Mobx5 proxy handler returns false for non-string keys, resulting in TypeError.
If Symbols where supported, could it conflict with current or future well-known symbols like: Symbol.iterator, Symbol.toStringTag, etc. ?
I don't think so. Symbols are accessible via Object.getOwnPropertySymbols(), returning an empty array on empty objects. The argument passed to observable/extendObservable represents simple property list - not an arbitrary "smart" object (eg an object implementing a well known symbol).
So if there is a symbol, it's introduced by user and should be made observable imho (no matter what symbol it is, similary to providing toString or valueOf).
@mweststrate What do you think about this issue?
:+1: from me also. We I'm trying to use symbols as keys for mixin attached private properties to a class and also make them observable, but mobx throws (up) :smile:
I think symbol named properties should probably behave the same as string named properties. That is, if they are enumerable, they should be picked up. Marking it as feature.
Contributions are welcome. Even a solid test suite would already give a great head start! Note that this has quite some impact on typings as well, as in things like extendObservable, keys and entries can have symbols in all positions where property names are returned now.
I guess ObservableMap could be left out of the equation for now?
@mweststrate Looking forward to this feature. I am trying the same thing with @dr0p , but mobx doesn't work.
`function decorateProp(params = {}) {
params = parseParams(params);
return function (target, name, descriptor) {
const privateName = Symbol(name); // `_${name}`;
params.observable(target, privateName, descriptor);
return computed(target, name, buildDescriptor(
params, privateName
));
};
}`
`mobx.module.js:98 Uncaught Error: [mobx] invalid option for (extend)observable: configurable
at invariant$$1 (mobx.module.js:98)
at fail$$1 (mobx.module.js:93)
at assertValidOption (mobx.module.js:424)
at Array.forEach (<anonymous>)
at asCreateObservableOptions$$1 (mobx.module.js:434)
at Function.object (mobx.module.js:498)
at Object.createObservable [as observable] (mobx.module.js:463)
at prop.js:49
at prop (prop.js:60)
at web.js:182433`
I'd like to make my own iterable an observable object, but this issue is preventing me from doing so : ). In this case though, the Symbol shouldn't be enumerable, preferably.
Basic use case for us is an iterable datastructure whose data source can differ (e.g. array or a generator function).
https://jsfiddle.net/jasperh/x7mz4k8w/8/
@jheeffer If I follow correctly, you don't need the symbol prop observable. So if you can live with some kind of factory function, you can introduce the iterator to observable object:
const bar = mobx.observable(foo)
Object.defineProperty(bar, Symbol.iterator, {
enumerable: false,
get() {
return this.x[Symbol.iterator].bind(this.x);
}
})
@urugator you're right, that could work too. Out of the box keeping an object iterable would be nice but I understand the trade-offs : )
馃憢 Hey folks, I've tried to kicked this off in PR #1944, please feel free to have a look n' review if you have the time.
Released as 4.10.0 / 5.10.0. Thanks @loklaan !
YES 馃帀
Most helpful comment
Mobx ignores non-enumerable props (like symbols) in
observable/extendObservable.The symbol is firstly introduced to the observable object during the assignment (in
incSymbol).Mobx4 doesn't support dynamic keys, so the standard JS behavior (new non-observable property is added to object) takes place, therefore no error.
In Mobx5 proxy handler returns false for non-string keys, resulting in TypeError.
I don't think so. Symbols are accessible via
Object.getOwnPropertySymbols(), returning an empty array on empty objects. The argument passed toobservable/extendObservablerepresents simple property list - not an arbitrary "smart" object (eg an object implementing a well known symbol).So if there is a symbol, it's introduced by user and should be made observable imho (no matter what symbol it is, similary to providing
toStringorvalueOf).