Watching a class for changes, in javascript
There are many cases in which it would be useful to watch a class and respond if it has been updated, either internally or externally. One example would be game update loops. If you are familiar with React, think of how `this.state` works and causes a re-render when updated.
Utilizing ES6 classes and a proxy / handler it is possible to pass a callback when instantiating the class. This callback will fire when a specified property is added or modified, essentially allowing us to subscribe to those changes.
Let’s jump into the code.
Create the class
Nothing too special happening here. We create our class and set up a bit of logic to allow for default options and for options to be specified when the class is instantiated.
Add the handler
Next we’ll create our updateHandler
which the proxy will use to process updates:
Our update handler defines a function, set
which we’ll use with proxy to intercept updates to the classes’ state and apply some additional logic. The set
function takes four arguments: target
, property
, value
, and receiver
. For more on these checkout the docs on MDN.
The notable lines above are:
obj[prop] = value;
obj.onUpdate();
The first sets the property and value, no surprises here. The second fires onUpdate
which we’ll create next, along with adding the state and proxying the set function to our handler.
Add state and proxy
We’ve just created our state object and provided the updateHandler
. We’ve also defined a function, classStateDidUpdate
, and assigned it to onUpdate
which we used above. classStateDidUpdate
will fire after a value is set on classState
pass the state object as an argument to a provided callback.
All together now
Putting it all together, we’ll instantiate our class and pass it the update callback:
Now we have a function, updateWatcher
, which will be called when the classState
is updated on our newly instantiated class.
Result
To see it in action paste the above gist into the developer console and then type: ourClass.updateState('testProp', 'testValue')
. You should get a response that looks like the following, confirming that the value was set and that our callback fired.