JavaScript Proxy with Storage

By  on  

The JavaScript Proxy API provides a wealth of "magic" within JavaScript, allowing you to use any object as sort of an alias that allows a wall of validation, formatting, and error throwing. Did you know that you could also employ the Proxy API as an abstraction to different types of storage? Whether it's sessionStorage, localStorage, or IndexedDB, you can use a proxy to make the API much easier to work with!

A very basic usage of the Proxy API is as follows:

/*
const proxy = new Proxy({}, {
  get: (obj, prop) => { ... },
  set: (obj, prop, value) => { ... },
  // more props here
});
*/

// This basic proxy returns null instead of undefined if the
// property doesn't exist
const proxy = new Proxy({}, {
  get: (obj, prop) => {
    return prop in obj ? obj[prop] : null;
  }
});

// proxy.whatever => null

The localStorage API is easy enough to use but employing a Proxy allows us to use the familiar object syntax and eventually even swap out the storage type without any other part of your code being effected.

function getStorage(storage, prefix) {
  return new Proxy({}, {
    set: (obj, prop, value) => {
      // obj[prop] = value;
      storage.setItem(`${prefix}.${prop}`, value);
    },
    get: (obj, prop) => {
      // return obj[prop];
      return storage.getItem(`${prefix}.${prop}`);
    },
  });
}

// Create an instance of the storage proxy
const userObject = getStorage(localStorage, "user");

// Set a value in localStorage
userObject.name = "David";

// Get the value from localStorage
const { name } = userObject;

Note: The code above is a very simplistic example -- you'd also want to add methods for deleting from the object, as well as try/catch to prevent storage errors!

You could swap localStorage for sessionStorage and there'd be very little effect on your overall code! If you do use storage in your app, you're likely already using and abstraction, but I love the basic JavaScript object interaction pleasing.

And I'm not the only one that loves this pattern. Firefox DevTools debugger uses this pattern to abstract the IndexedDB API for storing breakpoints, tabs, and other preferences!

Recent Features

  • By
    Create a CSS Cube

    CSS cubes really showcase what CSS has become over the years, evolving from simple color and dimension directives to a language capable of creating deep, creative visuals.  Add animation and you've got something really neat.  Unfortunately each CSS cube tutorial I've read is a bit...

  • By
    Responsive Images: The Ultimate Guide

    Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today's websites and devices become ever more varied, a plethora of responsive images...

Incredible Demos

  • By
    MooTools Star Ratings with MooStarRating

    I've said it over and over but I'll say it again:  JavaScript's main role in web applications is to enhance otherwise boring, static functionality provided by the browser.  One perfect example of this is the Javascript/AJAX-powered star rating systems that have become popular over the...

  • By
    Spoiler Prevention with CSS Filters

    No one likes a spoiler.  Whether it be an image from an upcoming film or the result of a football match you DVR'd, sometimes you just don't want to know.  As a possible provider of spoiler content, some sites may choose to warn users ahead...

Discussion

    Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!