Subscribe

Detect object changes with JavaScript Proxy

โœ๏ธ

How to detect object changes in JavaScript using the Proxy object

10 Jul, 2022 ยท 3 min read

Let's say we have an object for our users. How can we detect when a property changes?

const user = {
  firstName: 'Chris',
  lastName: 'Bongers',
  age: 10,
};

Now the user changes his age by using the following code.

user.age = 33;

However, we want to log this change to keep track of specific changes.

Using JavaScript Proxy to detect object changes

That's again where the Proxy object comes in handy. As we learned in the previous article, the Proxy object comes with a set handler (trap).

The set handler can pass us the following three parameters.

  • object: The whole object we are trying to modify
  • property: The property we are trying to modify
  • value: The new value we are trying to set

Let's create a proxy to our user object so we can attach a handler.

const handler = {
  set(target, prop, value) {
    // Our code
  },
};

const proxyUser = new Proxy(user, handler);

As for the code, we want to log which property is being changed, what the previous value was, and what the new value will be.

Then we need to ensure that we set the new value.

The result is the following function.

const handler = {
  set(target, prop, value) {
    console.log(`changed ${prop} from ${target[prop]} to ${value}`);
    target[prop] = value;
  },
};

Let's try it out by modifying the age again.

proxyUser.age = 33;

Now the console will show this change and log changed age from 10 to 33.

Detecting additional Object properties

Sometimes we might push new properties to the object. Let's see how we can capture that.

proxyUser.email = '[email protected]';

And again, this will neatly log the change: changed email from undefined to [email protected].

However, there is one small exception.

If we have a sub-object or array in our main object, it won't work out of the box.

const user = {
  firstName: 'Chris',
  lastName: 'Bongers',
  age: 10,
  address: {
    postalCode: '1234AB',
  },
};

proxyUser.address.postalCode = '5678CD';

This now logs nothing new, but the property is changed! And that's because there is now a deep proxy set.

To log on that level, we can again leverage the get handler and proxy each property to be a proxy itself ๐Ÿคฏ.

const handler = {
  get(target, key) {
    if (typeof target[key] === 'object' && target[key] !== null) {
      return new Proxy(target[key], handler);
    }
    return target[key];
  },
  set(target, prop, value) {
    console.log(`changed ${prop} from ${target[prop]} to ${value}`);
    target[prop] = value;
  },
};

And now, when we rerun our code, we see the log appear as changed postalCode from 1234AB to 5678CD.

I added these examples to CodePen so you can try them out yourself.

See the Pen JavaScript proxy a first introduction by Chris Bongers (@rebelchris) on CodePen.

Thank you for reading, and let's connect!

Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter

Spread the knowledge with fellow developers on Twitter
Tweet this tip
Powered by Webmentions - Learn more

Read next ๐Ÿ“–

Using the native payment request JavaScript API

9 Aug, 2022 ยท 8 min read

Using the native payment request JavaScript API

JavaScript if shorthand without the else

1 Aug, 2022 ยท 2 min read

JavaScript if shorthand without the else

Join 1748 devs and subscribe to my newsletter