-
-
Save olayemii/948e5f611ee3f83e811d0040a2f0c4d4 to your computer and use it in GitHub Desktop.
const getObjectProperty = (obj, path, defaultValue="", returnUndefined=true) => { | |
const checkForDefaultValue = value => | |
value !== undefined ? value : undefined; | |
if (path === undefined) { | |
return obj; | |
} | |
try { | |
const value = path.split('.').reduce((o, i) => o[i], obj); | |
if (value === undefined && returnUndefined) return value; | |
return value !== undefined ? value : checkForDefaultValue(defaultValue); | |
} catch (e) { | |
if (e instanceof TypeError) return checkForDefaultValue(defaultValue); | |
throw e; | |
} | |
}; | |
/* | |
const a = { | |
b: { | |
c: [ | |
{ | |
d: { | |
e: 14 | |
} | |
}, | |
[16, 11] | |
], | |
d: 12 | |
} | |
}; | |
getObjectProperty(a, 'b.d', "Default!"); | |
// 12 | |
getObjectProperty(a, 'b.e', "Not a property"); | |
// undefined | |
getObjectProperty(a, 'b.e', "Not a property", false); | |
// Not a property | |
getObjectProperty(a, 'b.c.0.d.e', "Not a property!"); | |
// 14 | |
getObjectProperty(a, 'b.c.1.0', "Not a property!"); | |
//16 | |
*/ |
@olayemii
The issue is that this line of code can result to undefined and since you used return
, undefined
will be returned
.
return path.split(".").reduce((o, i) => o[i], obj);
Try this in your browser's console with your original function:
const testObject = { a: 'A', b: 'B', c: [1, 2] };
getObjectProperty(testObject, 'd', 'Not Found');
// results in undefined instead of 'No Found'
getObjectProperty(testObject, 'd', 'Not Found');
I feel this should actually return undefined, because testObject.d
is actually having a value of undefined
My initial idea was that this
return path.split(".").reduce((o, i) => o[i], obj);
returns an undefined
except when we are trying to read from undefined like undefined.name
that is when the catch
block gets invoked and a defaultValue can be used.
Very well, for my use case the later function works. Maybe you should provide a flag.
Very well, for my use case the later function works. Maybe you should provide a flag.
@ahkohd okay, I added a flag to allow undefined returns or fall back to a set default value, I also included your example. 👌🏾
Great!
Hmm, @ahkohd I see, but in this case the value of
testObject.d
is actually undefined 🤔 Should the default value really suffice when it's not trying to read a property fromundefined
?