ES6 Proxy and Localization

Published 2018-01-01

Maybe you've heard of JavaScript Proxy and think, "Hey that's cool and such, but what should I use it for?" Don't worry, I thought this too until recently when I needed a catch-all solution. And BEHOLD, the indirect intermediary known only as "Proxy" arose from the ashes and set ablaze all Text Editors throughout the known universe.

In my use case, I wanted to pass back an object (more like a dictionary) that would contain key/value pairs for each localized string in the application. But the magic sauce here is that any missing string should return a See-No-Evil monkey emoji (๐Ÿ™ˆ) because that means the developer mistyped a letter or maybe the string wasn't translated at all! The monkey will not judge you.

Let's look at some example JSON that is emitted when a good ol' chap from across the pond visits our application (someone using en-GB).

{
  "color": "Colour",
  "elevator": "Lift",
  "pants": "Trousers"
}

At first, you might think that the ES5 Getter could solve our problem because you can override a property (such as elevator) and check if there is no value defined. But what about the keys you don't know about? You don't know what you don't know.

Enter the Proxy, where Bruce Lee plays a web developer determined to help capture the missing keys responsible for the death of his sister.

let obj = JSON.parse(json);
let l10n = new Proxy(obj, {
  get(target, name) {
    if (typeof target[name] === 'undefined') {
      console.error(`Localized string is missing: ${name}`);
      return '๐Ÿ™ˆ';
    }
    return target[name];
  }
});

We call the localization object l10n because we're lazy and this abbreviation is commonly used according to Wikipedia and other lazy devs. Ain't nobody got time for typing. Why am I writing this article anyway?

Now back to the topic of Proxy usage...let's talk about React.

React is great and you should use it because the internet told you so and that one blogger blogged about it on their weblog so don't challenge the blog. Embrace the blogosphere.

const SelectAColor = (props) => (
  <div>
  <label>{props.l10n.color}:</label>
  <select>
    {props.colors.map(c =>
      <option value={c}>
        {c}
      </option>)}
  </select>
  </div>
);

Now that we have a React component, let's see how it would render for users from different countries.

color-dropdown-localized

USA looks A-OK! Great Britain looks great! Mexico is ยกAy, caramba! We forgot to translate into Spanish! The monkey does not lie but the monkey is forgiving.

The same would happen if you misspelled props.l10n.color for example props.l10n.colr in which case, the monkey would visit you again, shielding its eyes from your incompetence.

If you would like to see a demo, visit CodeSandbox to see the code in action and witness the magnificent monkey madness!