Detect object changes with JavaScript Proxy

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
Search for a command to run...

I'm a full-stack developer from South Africa 🇿🇦. I love writing about JavaScript, HTML and CSS.
No comments yet. Be the first to comment.
Most of you know me for my consistency, a golden arrow in my blog series. I've written 1000 articles in 1008 days! Almost an article a day, and my honeymoon was the only holiday I ever took. I'm super proud of this achievement; it has been a fantasti...

It's not the first time I'll be talking about community. I think it's an essential aspect of any successful tool. This shows in my previous explorations of Astro, Medusa, and now Vendure as well. All these products thrive in a super open, welcoming, ...

The cool part about Vendure is how easy it is to set up and how abstract each layer is. Basically, we get the following elements: External database Server Worker Admin UI Frontend While this is amazing, it also brings a bit of complexity when it co...

The previous article looked at customizing Vendure on a data and process level. In this article, we'll look at customizing emails, as they are often a big part of a webshop system. We'll be looking at two different layers of customization for customi...

Even though Vendure is a pretty significant project out of the box, in some cases, we might want to go in and modify some elements to work to our specific use case. In this article, I'll take a high-level look at some elements we can customize within...

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.
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.
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.
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.
Thank you for reading my blog. Feel free to subscribe to my email newsletter and connect on Facebook or Twitter