Real world use cases of object proxies
Tags: javascript, webdev, programming, react
Published: 2022-09-10 16:47:07

---
title: Real world use cases of object proxies
published: true
description: A blog on how proxy can be leveraged to replace simple logic statements
tags: javascript, webdev, programming, react
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ksu7mr8rfxr18tgqu0ja.png
# Use a ratio of 100:42 for best results.
---

## Standard definition 
The Proxy object enables you to create a proxy for another object, which can intercept and redefine fundamental operations for that object.

![Thinking](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i9pjxwtq2yow8hk39plf.jpeg)

_Let's simplify that a little._

"Customise the behaviour of an object, using handlers" -- in a broad sense. 

## Target and Handlers

Target is the object of concern on which Proxy is applied

Handlers or traps are functions passed as second parameter to `Proxy` which are responsible to handle actions (such as `get`, `set` etc) on the target

```javascript
new Proxy(target, handler);
```

Let's look at some examples which will add weight around what the statement intends to convey.

## Handle defaults

Consider a script which is to be used to match the winners with prizes they have won and everyone who participated gets a consolation prize. 

A cleaner approach to coding it as opposed to a long list of `if-else` statements or switch is to use `Proxy`:

```javascript
const prizeRegistry = {
  karen: "First Prize - BMW X5",
  mark: "Second Prize - Scooty",
  athira: "Third Prize - Bicycle"
};

const prizeHandler = {
  get(obj, prop) {
    return prop in obj ?
      obj[prop] :
      "Consolation prize - Chocolate Bar";
  }
};

const prizeList = new Proxy(prizeRegistry, prizeHandler);

console.log(prizeList.karen);
// expected output: "First Prize - BMW X5"

console.log(prizeList.reena);
// expected output: "Consolation prize - Chocolate Bar"
```

## Input validations

With user inputs being a cog in the wheel to most of the applications today. Validations are to be placed to keep the data clean, ironically often as a result the code responsible gets messed up with time.

```javascript
const validator = {
  set(obj, prop, value) {
    if (prop === 'weight') {
      if (!Number.isInteger(value)) {
        throw new TypeError('The weight is not an integer');
      }
      if (value > 200) {
        throw new RangeError('The weight seems invalid');
      }
    }

    // The default behavior to store the value
    obj[prop] = value;

    // Indicate success
    return true;
  }
};

const fish = new Proxy({}, validator);

fish.weight = 100;
console.log(fish.weight); 
// expected output: 100
fish.weight = 'small';    // Throws an exception
fish.weight = 300;        // Throws an exception
```

## Finding an array item object by its property

```javascript
const products = new Proxy([
  { name: 'Firefox', type: 'browser' },
  { name: 'SeaMonkey', type: 'browser' },
  { name: 'Thunderbird', type: 'mailer' }
],
{
  get(obj, prop) {
    // The default behavior to return the value; prop is usually an integer
    if (prop in obj) {
      return obj[prop];
    }

    // Get the number of products; an alias of products.length
    if (prop === 'number') {
      return obj.length;
    }

    let result;
    const types = {};

    for (const product of obj) {
      if (product.name === prop) {
        result = product;
      }
      if (types[product.type]) {
        types[product.type].push(product);
      } else {
        types[product.type] = [product];
      }
    }

    // Get a product by name
    if (result) {
      return result;
    }

    // Get products by type
    if (prop in types) {
      return types[prop];
    }

    // Get product types
    if (prop === 'types') {
      return Object.keys(types);
    }

    return undefined;
  }
});

console.log(products[0]);          // { name: 'Firefox', type: 'browser' }
console.log(products['Firefox']);  // { name: 'Firefox', type: 'browser' }
console.log(products['Chrome']);   // undefined
console.log(products.browser);     // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }]
console.log(products.types);       // ['browser', 'mailer']
console.log(products.number);      // 3

```

The above snippet is from [mozilla documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#finding_an_array_item_object_by_its_property), showing how an object in an array of objects can be optimally found using proxy

There are a number of other real-world usecase(s) that could leverage the awesomeness of `Proxy` to better maintain and help keep the code cleaner. 

P.S These are the few i use day in and out, there are few more such as DOM manupulations, Property forwarding. You can check em out [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#manipulating_dom_nodes).

Hope this helps. Cheers :beers: