A JavaScript function which assures that a value of a child chain property is returned without runtime errors.
const obj = { | |
c: { | |
a: 2, | |
b: { | |
c: [1, 2, 3, {a: 15, b: 10}, 15] | |
}, | |
c: undefined, | |
d: null | |
}, | |
d: '' | |
} | |
/** | |
* Assures that a value of a child chain property is returned without runtime errors. | |
* | |
* If the checked property does not exist in the provided object or one of the children in the chain | |
* is undefined, then it returns the provided fallback value. | |
* | |
* The fallback can be also returned if the checked property is falsy (i.e. undefined, null, false, 0, '', etc.) | |
* and the fallbackOnFalsy flag is set to <TRUE>. | |
* | |
* Arrays could be checked as well by passing the index in the path; ex: getValue(arr, '0.obj') | |
* | |
* Note: if object or path params are not provided, the fallback is returned. | |
* | |
* @param {Object|Array} object - ordinary JSON object or array in which the property value is checked. | |
* @param {String | Array} path - object property access chain; ex: 'a.b.c' or ['a', 'b.c', 'd']. | |
* @param {*} fallback - the fallback value. | |
* @param {Boolean} fallbackOnFalsy - if true and the found property value is falsy then it returns the fallback. | |
* | |
* @returns {*} - the deepest property value or the fallback. | |
*/ | |
getValue(object, path, fallback, fallbackOnFalsy) { | |
if (!object || !path) { | |
return fallback; | |
} | |
if (typeof path === 'string') { | |
path = path.split('.'); | |
} | |
// Reduces object properties to the deepest property in the path argument. | |
return path.reduce((object, property) => { | |
if (object && typeof object !== 'string' && object.hasOwnProperty(property)) { | |
// The property is found but it may be falsy. | |
// If fallback is active for falsy values, the fallback is returned, otherwise the property value. | |
return !object[property] && fallbackOnFalsy ? fallback : object[property]; | |
} else { | |
// Returns the fallback if current chain link does not exist or it does not contain the property. | |
return fallback; | |
} | |
}, object); | |
} | |
// Same as get value but slightly unreadable. | |
// function getValue(o, path, fb, fbFalsy) { | |
// if(!o || !path) return fb; | |
// return path.split('.').reduce((o, p) => o && typeof o !== 'string' && o.hasOwnProperty(p) ? !o[p] && fbFalsy ? fb : o[p] : fb, o); | |
// } | |
// Shorter version. which does not apply fallback for falsy values, it just returnes what it finds. | |
// function getValue(o, path, fb) { | |
// if(!o || !path) return fb; | |
// return path.split('.').reduce((o, p) => o && typeof o !== 'string' && o.hasOwnProperty(p) ? o[p] : fb, o); | |
// } | |
// fallback | |
console.log(getValue(null, 'c.d.d', 'fallback')) | |
// fallback | |
console.log(getValue(obj, null, 'fallback')) | |
// fallback | |
console.log(getValue(null, null, 'fallback')) | |
// fallback | |
console.log(getValue(obj, 'c.d.d', 'fallback')) | |
// null | |
console.log(getValue(obj, 'c.d', 'fallback')); | |
// array | |
console.log(getValue(obj, 'c.b.c', 'fallback')); | |
// array index 2 | |
console.log(getValue(obj, 'c.b.c.2', 'fallback')); | |
// no index => fallback | |
console.log(getValue(obj, 'c.b.c.10', 'fallback')); | |
// array no index, no fallback => undefined | |
console.log(getValue(obj, 'c.b.c.10')); | |
// array's object property | |
console.log(getValue(obj, 'c.b.c.3.a')); | |
// array property length | |
console.log(getValue(obj, 'c.b.c.length', 'fallback')); | |
// prints falsy object | |
console.log(getValue(obj, 'c.c', 'fallback')); | |
// prints fallback for falsy values | |
console.log(getValue(obj, 'c.c', 'fallback', true)); | |
// prints fallback | |
console.log(getValue(obj, 'c.z.1', 'fallback')); | |
// prints fallback | |
console.log(getValue(obj, 'c.z.1', 'fallback', true)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment