Watch for Object Changes with JavaScript

By  on  

Watching for changes to an object's property has always been a much sought after task; many shims have been used over the years to listen to object changes.  These days we have better methods for listening to object changes:  the Proxy API.  Sindre Sorhus has created on-change, a tiny JavaScript tool that allows you to listen for changes on JavaScript objects and arrays!

on-change JavaScript

Since the on-change code is so tiny, here it is in its full glory:

'use strict';

module.exports = (object, onChange) => {
	const handler = {
		get(target, property, receiver) {
			try {
				return new Proxy(target[property], handler);
			} catch (err) {
				return Reflect.get(target, property, receiver);
			}
		},
		defineProperty(target, property, descriptor) {
			onChange();
			return Reflect.defineProperty(target, property, descriptor);
		},
		deleteProperty(target, property) {
			onChange();
			return Reflect.deleteProperty(target, property);
		}
	};

	return new Proxy(object, handler);
};

The onChange function returns a proxy which you'll use to make any object changes.

Using on-change

Pass onChange the object you'd like to spy on and a change handler function:

let j = {
    a: 1
};

// Upon change, save to server
let changeable = onChange(j, () => save(j));

Then use that Proxy to change properties and get notified of changes:


// Make a change that would trigger changes
changeable.a = 2;

// save() is triggered!

// j.a === 2

Note that the original object's values also change -- that's the beauty of Proxy!  Also note that on-change doesn't tell you which property changed; the use case, as Sindre describes, is saving an object (to server, etc.) when any part of an object changes.  You could also use ti for a small library with a render function, re-rendering the content whenever a property changed!

This on-change library is really nice if you don't need to know which property changed, just that something changed.

Recent Features

  • By
    Being a Dev Dad

    I get asked loads of questions every day but I'm always surprised that they're rarely questions about code or even tech -- many of the questions I get are more about non-dev stuff like what my office is like, what software I use, and oftentimes...

  • By
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

Incredible Demos

  • By
    JavaScript Battery API

    Mozilla Aurora 11 was recently released with a bevy of new features. One of those great new features is their initial implementation of the Battery Status API. This simple API provides you information about the battery's current charge level, its...

  • By
    background-size Matters

    It's something that makes all men live in fear, and are often uncertain of. It's never spoken, but the curiosity is always there. Nine out of ten women agree in the affirmative. Advertisers do their best to make us feel inadequate but...

Discussion

  1. If someone wonders what this Reflect object it. I stumbled across on-change a few days ago and wrote about it. :)

    https://www.stefanjudis.com/today-i-learned/the-global-reflect-object-its-use-cases-and-things-to-watch-out-for/

  2. Dave

    Just a note that watching an object really bogs down all accesses to the object. It’s great for debugging but don’t build a lot of functionality around it in your production code.

  3. Raj

    It is worth mentioning that arrays are not handled by this function and push/pop/delete to an array needs to be handled by overwriting those methods.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!