1

I'm trying to listen when a object value changes using a Javascript proxy object in a easy and readable way. I followed this Stack Overflow question and Mozilla docs. But I cannot understand how to do it to achieve my goal.

var values ={Value1: 0, Value2:0};
var checkObjectChange = new Proxy(values, {});

console.log("The object values are: "+JSON.stringify(values))

$("#btn1").on("click", function() {
    values.Value1 = 1;
    console.log("Now the object values are: "+JSON.stringify(values));
});

$("#btn2").on("click", function() {
    values.Value2 = 1;
    console.log("Now the object values are: "+JSON.stringify(values));
});

//Im expecting to call a function when a object value changes
function whenChange() {
  console.log("The value of the object has changed!");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="btn1">Change value 1</button>
<button id="btn2">Change value 2</button>
Brian Tompsett - 汤莱恩
  • 5,195
  • 62
  • 50
  • 120
SilverSurfer
  • 3,810
  • 2
  • 17
  • 36
  • 2
    You would actually need to assign to the properties of the proxy. If you are changing the original `values` object, the proxy does not notice. Also you must of course provide some traps to the proxy, or it is useless. – Bergi Jul 28 '19 at 13:30

1 Answers1

1

You can pass the handler function to Proxy and you need to change values on proxies not on original object

var values ={Value1: 0, Value2:0};

let handler = {
  set: function whenChange(obj,prop,value) {
    obj[prop] = value
  console.log("The value of the object has changed!");
  return true
 }
}
var checkObjectChange = new Proxy(values, handler);

console.log("The object values are: "+JSON.stringify(checkObjectChange))

$("#btn1").on("click", function() {
    checkObjectChange.Value1 = 1;
    console.log("Now the object values are: "+JSON.stringify(checkObjectChange));
});

$("#btn2").on("click", function() {
    checkObjectChange.Value2 = 1;
    console.log("Now the object values are: "+JSON.stringify(checkObjectChange));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button id="btn1">Change value 1</button>
<button id="btn2">Change value 2</button>
Code Maniac
  • 33,907
  • 4
  • 28
  • 50
  • Nice, this is what I was expecting, a few questions, is it function name `whenChange` required for this case, can be without a name? What does it mean `obj[prop] = value`? If you remove that and print `value` it has the same as you use assing `obj[prop] = value`. And the difference between `var` and `let` in this case? – SilverSurfer Jul 28 '19 at 13:56
  • @SilverSurfer you can use any name it's upto you, `obj[prop] = value` is used to set the value on target object, you can read here more [`handle.set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set), Not much i have a habit of using `let` – Code Maniac Jul 28 '19 at 14:05
  • Ok, thanks, last question, do you think is cleaner `var checkObjectChange = new Proxy(values, { //Put the code handler here directly });` instead of define a separated `let handler object` like your example?. Is there any difference? – SilverSurfer Jul 28 '19 at 14:09
  • @SilverSurfer no difference unless you modify the `handler` somewhere in your code, while in the later one you don't have access to `handler` so there's no case it can be modified later on – Code Maniac Jul 28 '19 at 14:24