Search code examples
nw.jsobject.observe

Transitioning away from Object.observe


I've been using Object.observe() as part of a nw.js project that is now transitioning from nw.js v.0.12.3 to latest.

I have code like this:

..(myclass)..
data: { a:0, b:42 },
setupHandlers: function () {
    Object.observe(this.data, changes => this.draw());
},
draw: function () { .. }

My initial conversion looks like:

data: {_a: 0, _b: 42},
get a() { return this._a; }
set a(val) { this.data._a = val; this.draw(); } 
get b() { return this._b; }
set b(val) { this.data._b = val; this.draw(); } 

and then change every place that wrote to data (myobj.data.a = 1) to instead write to the object (myobj.a = 1), thus using the setter.

It's a very labor-intensive conversion, is there an easier way?


Solution

  • We ended up using Proxy to catch attribute assignment:

    const shallow_observer = function (obj, fn) {
        return new Proxy(obj, {
            set(target, name, val) {
                target[name] = val;
                if (fn) fn(target, name, val);
                return true;
            }
        });
    };
    

    which allowed us to do:

    data: { a:0, b:42 },
    setupHandlers: function () {
        this.data = shallow_observer(this.data, (data, field, value) => this.draw());
    },
    draw: function () { .. }
    

    We have a deep_observer function too (which is much more complex), that detects changes in a nested data structure, but the shallow_observer was sufficient for all our use-cases.