-
-
Notifications
You must be signed in to change notification settings - Fork 126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
deepObserve not working with ObservableSet #298
Comments
Proposed change: https://github.com/mobxjs/mobx-utils/blob/master/src/deepObserve.ts#L101 function observeRecursively(thing: any, parent: Entry | undefined, path: string) {
if (isRecursivelyObservable(thing)) {
const entry = entrySet.get(thing)
if (entry) {
if (entry.parent !== parent || entry.path !== path)
// MWE: this constraint is artificial, and this tool could be made to work with cycles,
// but it increases administration complexity, has tricky edge cases and the meaning of 'path'
// would become less clear. So doesn't seem to be needed for now
throw new Error(
`The same observable object cannot appear twice in the same tree,` +
` trying to assign it to '${buildPath(parent)}/${path}',` +
` but it already exists at '${buildPath(entry.parent)}/${entry.path}'`
)
} else {
const entry = {
parent,
path,
dispose: observe(thing, genericListener),
}
entrySet.set(thing, entry)
entries(thing).forEach(([key, value]) => observeRecursively(value, entry, key))
}
// the else is added.
} else if (isObservableSet(thing)) {
const entry = {
parent,
path,
dispose: observe(thing, genericListener),
}
entrySet.set(thing, entry)
}
} Tested and works on: import {observable, runInAction} from 'mobx';
import {deepObserve} from 'mobx-utils';
const set = observable.set([1, 2, 3]);
deepObserve(set, (change, path, root) => console.log(change, path, root));
runInAction(() => set.add('bla')); At first, I didn't add the import {observable, runInAction} from 'mobx';
import {deepObserve} from 'mobx-utils';
const obj = observable({
bla: true,
set: observable.set([1, 2, 3])
});
deepObserve(obj, (change, path, root) => console.log(change, path, root));
runInAction(() => obj.set.add('bla')); With the following error:
|
Another proposed solution: https://github.com/mobxjs/mobx-utils/blob/master/src/deepObserve.ts#L32 function isRecursivelyObservable(thing: any) {
return isObservableObject(thing) || isObservableArray(thing) || isObservableMap(thing) || isObservableSet(thing);
} After thinking about it, an ObservableSet can also be recursively observable (since it can hold observables). Therefore it shouldn't be treated differently from the other types. Needless to say that code that failed before now works |
Does it work for non-stringable entries? Set's values are also it's keys, so I wonder what happens with |
Hmmm good point, I think that the entries in a Set are the items themselves as well, so that means that the path will probably be a |
…only be observed shallowly mobxjs#298, mobxjs#312
repro:
console output:
Notice how in
console.log(set)
it has no observers.The text was updated successfully, but these errors were encountered: