DEV Community

Jitesh Dhamaniya
Jitesh Dhamaniya

Posted on

Get Nested Property from a Object in JS

Recently Stumbled upon this nice snippet for accessing Nested property using String.

 * get property of object
 * @param obj object
 * @param path e.g
function getProperty(obj, path, defaultValue = '-') {
    const value = path.split('.').reduce((o, p) => o && o[p], obj);

    return value ? value : defaultValue;
Enter fullscreen mode Exit fullscreen mode

and this how you use it

getProperty(object, '')
Enter fullscreen mode Exit fullscreen mode


Would be interested to learn if there is any other easier or better way.

Top comments (1)

tominoff profile image
Tominov Sergey • Edited

I think you should never use naive boolean conversion for such things because JS has at least 6 falsy types which can be used as regular values. This function you showed, gives you false positive result when you try extract that kind of values:

const obj = { 
  a: { 
    b1: false, 
    b2: null, 
    b3: undefined, 
    b4: NaN, 
    b5: 0, 
    b6: ''

getProperty(obj, 'a.b1') // '-'
getProperty(obj, 'a.b2') // '-'
getProperty(obj, 'a.b3') // '-'
getProperty(obj, 'a.b4') // '-'
getProperty(obj, 'a.b5') // '-'
getProperty(obj, 'a.b6') // '-'
Enter fullscreen mode Exit fullscreen mode

Instead of naive boolean conversions to check if object property exists always use .hasOwnProperty.👍 As a possible solution for your needs (return some defaults if path is incorrect) you can use symbols:

const NOT_FOUND_SYMBOL = Symbol('function:getProperty:notFound')

function getProperty (obj, path, defaultValue = '', pathDelimiter = '.') {
  const pathValue = path
    .reduce((prev, curr) => {
      // when not found we don't need to go deeper, kind of early exit
      return (prev !== NOT_FOUND_SYMBOL && prev.hasOwnProperty(curr)) 
        ? prev[curr] 
    }, obj)

  return pathValue !== NOT_FOUND_SYMBOL ? pathValue : defaultValue

const obj = {
  a: { b: { 
    c1: null,
    c2: false,
    c3: NaN,
    c4: '',
    c5: 0,
    c6: undefined,
    c7: `It's ok`

console.log(getProperty(obj, 'a.b.c0', 'Path is incorrect')) // 'Path is incorrect'
console.log(getProperty(obj, 'a.b.c1', 'Path is incorrect')) // null
console.log(getProperty(obj, 'a.b.c2', 'Path is incorrect')) // false
console.log(getProperty(obj, 'a.b.c3', 'Path is incorrect')) // NaN
console.log(getProperty(obj, 'a.b.c4', 'Path is incorrect')) // ''
console.log(getProperty(obj, 'a.b.c5', 'Path is incorrect')) // 0
console.log(getProperty(obj, 'a.b.c6', 'Path is incorrect')) // undefined
console.log(getProperty(obj, 'a.b.c7', 'Path is incorrect')) // "It's ok"
Enter fullscreen mode Exit fullscreen mode