Skip to content

Instantly share code, notes, and snippets.

@jpitchardu
Last active June 5, 2020 02:31
Show Gist options
  • Save jpitchardu/76e3bb814b86d5a8860f9a2956e827ad to your computer and use it in GitHub Desktop.
Save jpitchardu/76e3bb814b86d5a8860f9a2956e827ad to your computer and use it in GitHub Desktop.
Optional API javascript
function optionalAccess(obj, path, def) {
const propNames = path.replace(/\]|\)/, "").split(/\.|\[|\(/);
return propNames.reduce((acc, prop) => acc[prop] || def, obj);
}
function proxyOptional(obj, evalFunc, def) {
const handler = {
get: function(target, prop, receiver) {
const res = Reflect.get(...arguments);
return typeof res === "object" ? proxify(res) : res != null ? res : def;
}
};
const proxify = target => {
return new Proxy(target, handler);
};
return evalFunc(proxify(obj, handler));
}
const obj = {
items: [{ hello: "Hello" }]
};
console.log(optionalAccess(obj, "items[0].hello", "def")); // Prints Hello
console.log(optionalAccess(obj, "items[0].he", "def")); // Prints def
console.log(proxyOptional(obj, target => target.items[0].hello, "def")); // Prints Hello
console.log(proxyOptional(obj, target => target.items[0].hell, { a: 1 })); // Prinst { a: 1 }
console.log((obj && obj.items && obj.items[0] && obj.items[0].hello) || "def"); // Prints Hello
console.log((obj && obj.items && obj.items[0] && obj.items[0].hel) || "def"); // Prints def
@joshhopkins
Copy link

joshhopkins commented Sep 5, 2018

Nice. The proxyOptional function can also work well as Object.prototype:

Object.prototype.optional = function (evalFunc, def) {
    const handler = {
        get: function(target, prop, receiver) {
        const res = Reflect.get(...arguments);
        return typeof res === "object" ? proxify(res) : res != null ? res : def;
        }
    }

    const proxify = target => {
        return new Proxy(target, handler);
    }

    return evalFunc(proxify(this, handler));
}


// Example
const greeting = {
    items: [{ hello: undefined}],
}
 
result = greeting.optional(obj => obj.items[0].hello, null)
console.log(result) // prints null

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment