Mobx: Observe changes in complete objects graph

Created on 29 Jun 2016  ·  16Comments  ·  Source: mobxjs/mobx

Hi, just spent few hours trying to get answer for simple question, I am using Typescript and MobX for tracking changes, for example I have this classes:

`export class Area {
constructor(jsonData: Area) {
this.areaId = jsonData.areaId;
this.title = jsonData.title;
this.description = jsonData.description;
this.priority = jsonData.priority;
this.isActive = jsonData.isActive;
this.isVisible = jsonData.isVisible;
this.lastModified = jsonData.lastModified;
this.draft = jsonData.draft;
this.geometry = Geometry.instantiate(jsonData.geometry);
}
@observable
public areaId: string;
@observable
public title: string;
@observable
public description: string;
@observable
public priority: number;
@observable
public isActive: boolean;
@observable
public isVisible: boolean;
@observable
public geometry: Geometry;
@observable
public draft: boolean;
@observable
public lastModified: number;
}

export class AreaEnvelope {
constructor(jsonData: AreaEnvelope) {
this.area = new Area(jsonData.area);
this.lastPublished = jsonData.lastPublished;
this.color = jsonData.color;
this.opacity = jsonData.opacity;
this.resources = jsonData.resources;
}
@observable
public area: Area;
@observable
public lastPublished: number;
@observable
public color: string;
@observable
public opacity: number;
@observable
public resources: Geofence[];
}`

Then when I am trying to use "observe" function on AreaEnvelope object, detecting changes works only for its own properties, and not for "Area" object properties. According to description I got that by default Mobx do not observe nested not plain objects, but when you use 'extendObservable' in constructor or '@observable' decorators it should track nested object. Can you point me to solutions, where I can observe all object graph at once? Also is it possible to do that from outside, so object do not have any references to MobX functionalities, like '@observable' decorators?

Cheers

❔ question 💀 wontfix

Most helpful comment

[spam-cross-post-shame]
Hi, I don't know if someone is still interested by a deep observer for mobx but I build something like that here: https://github.com/dagatsoin/mobx-deep-observer
It is still an alpha version and would need some testers.
[/spam-cross-post-shame]

All 16 comments

@lutsykigor MobX doesn't have a concept for deep observing change. (extendObservable is just a variance of @observable). But MobX can react to changes that happen deeply in an object using reactions, like for example autorun. So in autorun you can walk your object tree, and if any part of the object tree you visited changes in the future, the autorun will automatically re-run. In most cases (except when you really need to know object diffs) this is a simpler alternative to deep observe. I hope that helps! Otherwise, please elaborate what you want to achieve in your deepObserving function.

Thanks for super fast response.
'autorun' is perfect fit for me.

Questions is closed.
Thanks one more time. Great product.

Just have short additional question.
autorun works as expected if I marked class properties with @observable decorator.
But when I remove those decorations, autorun function is fired everytime I am making some change to object's tree, but those changes are not visible within object reference. Is it expected behavior? It could be really handy to avoid having many @observable decorators, and relations to MobX from domain classes.

Thanks

@lutsykigor sorry, missed this comment entirely! I didn't get the question entirely though, could you elaborate a bit if this is still a question? And otherwise close this issue ;-) ?

I meant that autorun does not detect changes on fields which are not marked with @observable decorator

For example I have this autoruncode snippet:
autorun(() => this.changeHandler(model));

So every time I made some change to model object, autorun invokes my changeHandler function, but when change were made to the model property which was not marked with @observable decorator, I can't see that change in changeHandler function, I see old value instead.

Hope this makes some sense...

Can you cut a quick fiddle showing this issue?

On Mon, Jul 18, 2016 at 9:25 AM, lutsykigor [email protected]
wrote:

I meant that autorun does not detect changes on fields which is not
marked with @observable decorator

For example I have this autoruncode snippet:
autorun(() => this.changeHandler(model));

So every time I made some change to model object, autorun invokes my
changeHandler function, but when change were made to the model property
which was not marked with @observable decorator, I can't see that change
in changeHandler function, I see old value instead.

Hope this makes some sense...


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/374#issuecomment-233343922, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAIrclJtuQaCNuuEorBxu_Los8lQ6_A_ks5qW4zQgaJpZM4JBAdC
.

-Matt Ruby-
[email protected]

@lutsykigor if I understand your comment correctly, then this is expected behaviour. autorun() fires only if the used observable is changed. So it will not fire for properties that are unobserved.

@mattruby Sorry I can't make quick fiddle as it is TypeScript + Node package.

@hellectronic I were thinking exactly that way, it is logical, but my observed behavior was that autorun is fired every time when I change not observable property, but change is not visible in autorun, I see old value instead.

I will try to prepare some demo layer today.

Hi, I've been trying to figure this out and I concluded as @mweststrate pointed out that you can't get "diffs" using just mobX, am I wrong? I'm attempting to create an isomorphic stack where any change on the server gets sent to the browser, which could easily(?) be achieved with Proxy objects, but wouldn't be well supported on browsers for a while...

Unless someone can provide a better solution, I believe that either I create a setter/getter function to wrap this logic or as described before I could try emulate react components that instead "spit-out" json and get "diffed". Both sound more intrusive than I wished :(

if you set up observe per object you can easily generate patch / diff data

Op za 6 aug. 2016 00:10 schreef alexmipego [email protected]:

Hi, I've been trying to figure this out and I concluded as @mweststrate
https://github.com/mweststrate pointed out that you can't get "diffs"
using just mobX, am I wrong? I'm attempting to create an isomorphic stack
where any change on the server gets sent to the browser, which could
easily(?) be achieved with Proxy objects, but wouldn't be well supported on
browsers for a while...

Unless someone can provide a better solution, I believe that either I
create a setter/getter function to wrap this logic or as described before I
could try emulate react components that instead "spit-out" json and get
"diffed". Both sound more intrusive than I wished :(


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/mobxjs/mobx/issues/374#issuecomment-237977843, or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABvGhM1nN75xo4VBmB-zN5StRvpHtiWOks5qc7TEgaJpZM4JBAdC
.

@mweststrate what about nested objects? I'm talking large object graphs, setting individual observers could mean millions or more instances.

you could spy, but that catches everything. Individual observers are not expensive to create. At least lot's cheaper than diffing millions of instances :) I plan to provide some standard stuff for this in the near feature, on top of MobX but for now creating observers is the way to go (note that you can observe per instance, and the handler can be the same for every object as change.object refers to the targetted object)

See also #214. This won't be fixed within mobx, for the simple reason that for clear semantics a deep observer should operate on trees, and not on arbitrarily object graphs. Stay tuned though, I'm thinking about some abstraction on top of mobx that have this restriction allowing this kind of functionality.

[spam-cross-post-shame]
Hi, I don't know if someone is still interested by a deep observer for mobx but I build something like that here: https://github.com/dagatsoin/mobx-deep-observer
It is still an alpha version and would need some testers.
[/spam-cross-post-shame]

mobx-utils now exposes a deepObserve utility as well: https://github.com/mobxjs/mobx-utils#deepobserve

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs or questions.

Was this page helpful?
0 / 5 - 0 ratings