Watch.JS icon indicating copy to clipboard operation
Watch.JS copied to clipboard

Watcher not called when assigning a function to the watched attribute

Open Maluen opened this issue 12 years ago • 2 comments

Description:

The watcher is not called when assigning a function to the watched attribute if the watcher has never been called before.

Example:

// Doesn't work
var obj1 = {};
watch(obj1, "attr", function (prop, action, difference, oldvalue) {
    alert("obj1, prop: "+prop+"\n action: "+action+"\n difference: "+JSON.stringify(difference));
});
obj1.attr = function() {
    return "foo";
}

// Works!
var obj2 = {};
watch(obj2, "attr", function (prop, action, difference, oldvalue) {
    alert("obj2, prop: "+prop+"\n action: "+action+"\n difference: "+JSON.stringify(difference));
});
obj2.attr = "a";
obj2.attr = function() {
    return "foo";
}

// Doesn't work
var obj3 = {};
watch(obj3, "attr", function (prop, action, difference, oldvalue) {
    alert("obj3, prop: "+prop+"\n action: "+action+"\n difference: "+JSON.stringify(difference));
});
callWatchers(obj3, "attr"); //invoke the handler​​
obj3.attr = function() {
    return "foo";
}

Try it on jsFiddle

Maluen avatar Mar 01 '13 16:03 Maluen

Good point! Thank you for your feedback. I will check this cases with more time to think a good way to fix this, be welcome to suggest something. Thank you again.

melanke avatar Mar 01 '13 17:03 melanke

In watch.js, line 276:

if (!WatchJS.noMore){
    if (JSON.stringify(oldval) !== JSON.stringify(newval)) {
        callWatchers(obj, prop, "set", newval, oldval);
        WatchJS.noMore = false;
    }
}

When assigning a function to the previously undefined watched attribute, the situation is as follows:

  • oldval == undefined => JSON.stringify(oldval) == undefined
  • typeof newval == function => JSON.stringify(newval) == undefined (JSON doesn't understand functions)

So the callWatchers function is never called

Maluen avatar Mar 01 '13 18:03 Maluen