Skip to content

Instantly share code, notes, and snippets.

@Kapott
Last active July 19, 2019 09:40
Show Gist options
  • Save Kapott/97571edec2b1627a741bb7c4a8cfe2cb to your computer and use it in GitHub Desktop.
Save Kapott/97571edec2b1627a741bb7c4a8cfe2cb to your computer and use it in GitHub Desktop.
Get deeply nested object properties, ES5 compatible - good replacement for LoDash' .get()
/**
* getDeep(object, pathString, defaultValue)
*
* Tries to find the pathString inside the object. Returns defaultValue if any
* check along the way returns undefined.
*
* ES5 compatible, for when you need to support things like IOT toasters running IE6
* or shamefully out-of-date SAP/Citrix combinations.
*
* Replaces lengthy checks like this:
*
* var foo = (typeof obj != 'undefined'
* && obj.length > 0
* && typeof obj[1].prop1 !== 'undefined'
* && typeof obj[1].prop1.prop2 !== 'undefined'
* && typeof obj[1].prop1.prop2["prop.3"] !== 'undefined')
* ? obj.prop1.prop2["prop.3"]
* : null;
*
* with checks like this:
* var foo = getDeep(obj, 'obj[1].prop1.prop2["prop.3"]', null);
*
*/
var getArrayIndexFromString = function (str) {
var containsArray = /\[(\d+)\]/g;
var idx = containsArray.exec(str);
return (idx !== null) ? idx[1] : null;
};
var walkThroughObj = function(total, currentValue) {
if (typeof total == 'undefined' || total === null) { return null; }
var idx = getArrayIndexFromString(currentValue);
var objArrName = currentValue.slice(0, currentValue.indexOf('['));
var format = idx ? total[objArrName][parseInt(idx)] : total[currentValue];
return (typeof format !== "undefined") ? format : null;
};
var getDeep = function (obj, path, defaultValue) {
var result = String.prototype.split.call(path, /(\w+\[\d\])|(\W)/)
.filter(Boolean)
.filter(function(e) { return e.match(/^\w+/g); })
.reduce(walkThroughObj, obj);
return (typeof result == "undefined" || result === null || result === obj) ? defaultValue : result;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment