---
title: "Javascript&#8217;s Proxy is neat"
date: 2023-09-27T18:17:02
slug: javascripts-proxy-is-neat
tags: [code, javascript]
---
So last week I went to [State of the Browser](https://2023.stateofthebrowser.co.uk). I had a great time, met some really interesting people, and got to see some great talks. 

One talk in particular was on [Two-way data binding by Chris Ferdinandi](https://gomakethings.com/two-way-data-binding-and-reactivity-with-15-lines-of-vanilla-javascript/). The general gist of it is that you can use the [Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) object, which can intercept operations when a value is set, to perform UI updates.

So I thought I'd use it to power the colour scheme picker on my blog. Here's the code:

```javascript
const defaultColourScheme = () => {
	if (localStorage.getItem('color-scheme')) {
		return localStorage.getItem('color-scheme');
	}

	if (window.matchMedia('(prefers-color-scheme: dark)')?.matches) {
		return "dark";
	}

	return "light";
};

const data = new Proxy({
	'color-scheme': defaultColourScheme(),
}, {
	set: (obj, key, value) => {
		obj[key] = value;
		localStorage.setItem(key, value);
		document.body.setAttribute(`data-${key}`, value);

		return true;
	}
});

const onRadioChange = e => {
	data[e.target.name] = e.target.value;
}

document.querySelectorAll('[name="color-scheme"]').forEach(radio => {
	radio.addEventListener('change', onRadioChange);
	radio.checked = data[radio.name] == radio.value;
});
document.body.setAttribute(`data-color-scheme`, localStorage.getItem('color-scheme'));
```

The really important parts are between lines 20-30. Basically, when a property is updated, it gets synced to `localStorage` and set as a `data-` attribute on the body element (which I use for CSS targeting).

It works pretty well! It even initialises with the right values if the user is a first-time visitor. And the code is fairly short; originally I was going to use a WebComponent, but the state management ended up being quite verbose.

