Skip to content

Instantly share code, notes, and snippets.

@cerebrl
Created February 12, 2015 21:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cerebrl/a52b69aafa9bf820bb1e to your computer and use it in GitHub Desktop.
Save cerebrl/a52b69aafa9bf820bb1e to your computer and use it in GitHub Desktop.
Be able to safely access props on deep objects. Demo: http://jsbin.com/beferuviqo/1/edit
// Sample object
var mySampleData = {
foo: {
bar: [
1,
2,
{
baz: "hello",
wut: 2,
hi: [7, 8, 9]
}
],
size: "large",
party: "hard",
really: {
yeah: ["right?", "I'm working!"]
}
}
};
/**
* This function accepts an object and a property path to ensure safe prop access
* @function safeGet
* @param obj {object} The object that should contain the prop
* @param path {string} The path of properties that should access the wanted value
* @return {*} Returns the value of the property or null if it doesn't exist
*/
function safeGet (obj, path) {
var arr = path.split('.'), // Create array of props
currentPos = obj, // Start at whole object
i = 0,
len = arr.length,
objProp = '',
arrIdx,
openBracketIdx,
closeBracketIdx;
/** Loop over the given props */
for (i; i < len; i++) {
openBracketIdx = arr[i].indexOf('[');
closeBracketIdx = arr[i].indexOf(']');
/** Is this property a prop and array index? E.g.: prop[index] */
if (openBracketIdx !== -1) {
objProp = arr[i].slice(0, openBracketIdx); // Grab prop
arrIdx = arr[i].slice(openBracketIdx + 1, closeBracketIdx); // Grab index
/** Does the current prop exist on the object?
* If not, return null.
*/
if (!currentPos[objProp]) {
return null;
}
/** Since the prop does exist, grab the index off the prop and
* save to current position
*/
currentPos = currentPos[objProp][arrIdx];
/** Is this the last prop on the string?
* If yes, return the value of prop.
*/
if (len - i === 1) {
return currentPos;
}
} else if (currentPos[arr[i]]) { // If just a plain obj property
currentPos = currentPos[arr[i]];
/** Is this the last prop on the string?
* If yes, return the value of prop.
*/
if (len - i === 1) {
return currentPos;
}
} else { // Prop does not exist, so return null
return null;
}
}
}
var negativeTest = safeGet(mySampleData, "foo.bar[1].foo.none");
console.log("This is the negative test: " + negativeTest);
var positiveTest = safeGet(mySampleData, "foo.really.yeah[1]");
console.log("This is the positive test: " + positiveTest);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment