Skip to content
This repository has been archived by the owner on Mar 13, 2018. It is now read-only.

Add a DeepObserver to recursively observe an object, all its properties, all their properties, etc.... #80

Open
0x24a537r9 opened this issue Jan 24, 2015 · 4 comments

Comments

@0x24a537r9
Copy link

Currently observe-js doesn't have any support for a DeepObserver-like object which listens for changes to an object and all its recursive subobjects. A quick search also shows I'm not the first to notice its absence:

Indeed, I've also seen requests for it on internal mailing lists at my company. It seems to be a common expectation that observe-js would provide one. And from a completeness standpoint, it's a bit odd that observe-js doesn't at least offer some basic solution, even if it makes sense to build your own if your requirements are different from the provided deep observer.

As it turns out, a few other observation libraries already implement their own:

As it turns out, it's not as simple a task as it might seem to build a deep observer that cleans up after itself--it's a surprisingly difficult thing to do 100% correctly. And unfortunately, I was able to find several failed attempts as projects on their own:

I think it would be worthwhile for observe-js to provide a well-tested canonical solution. To that end (and for my own projects), I pulled together a basic DeepObserver at http://jsfiddle.net/3ju5qdb2/11/. It recursively observes an object and all of its properties all the way down, allocating as few ObjectObservers as possible and making sure to clean up after itself. It doesn't handle cycles, nor are the added/remove/changed event args as useful as they could be, since they only reflect the change at the lowest level, rather than the entire path. Neither matter for our application, but they wouldn't be hard to add to make the class more generally useful.

Perhaps something like it could be added to observe-js, or as an add-on for it making it opt-in?

@jmesserly
Copy link
Contributor

This is an excellent write up @0x24a537r9!

I have a few minor code review comments about the linked code but it does seem to be on the right track.

Some high level challenges with Obj.observe and deep observers that are worth thinking about. One issue is they can't tell what exactly happened during the microtask:

var obj = {};
obj.a = {};
delete obj.a;

vs

var obj = {};
obj.a = {x};
// this will not be observed
obj.a.x = 123;
delete obj.a;

in both cases, it will notice "a" was added and removed, but it wouldn't know what happened to "a" during that timeframe. Then again, one could argue that's a feature :). A related issue, when a new child object shows up, should deepobserver report that object's children as "new keys"? they might not actually be new.

Another challenge is cycles in the object graph: are they supported, and if so, how do the changes get reported?

Anyway it's neat to think about. It seems definitely worth putting your code in a repository so folks can reuse it.

@alex88
Copy link

alex88 commented Jun 3, 2015

Any updates on this?

@dsschnau
Copy link

dsschnau commented Nov 5, 2015

+1 ... is this a thing that will be looked at or left on the backburner for now?

@jmesserly
Copy link
Contributor

I think we're leaning away from collecting Observe utilities in this repository. But that said, it's great to write them and put them in their own repos/packages.

BTW, new development on this package is kind of on hold (https://esdiscuss.org/topic/an-update-on-object-observe), but the current polyfill implementation will continue to work.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants