2

If I had an object:

var dog= {
  name: "Max",
  age: 5,
  sex: undefined,
  details: {
    color: "black",
    breed: undefined
  }
}

And I wanted to get the paths of the properties with undefined values. How could I iterate through all of the properties, including the nested ones?

Currently, I have this vanilla js method for an object without nested properties:

function getUndefinedPaths(o, name) {
  var paths = [];
  for (var prop in o) {
    if (o[prop] === undefined) {
        paths += name + "." + prop + "\n";
    }
  }
  return paths;
}

// getUndefinedPaths(dog, "dog") only returns "dog.sex" and not "dog.details.breed" which is also undefined.

I'm stuck. Can someone help out on how to get paths of those undefined values in a nested property of a js object? I'm attempting this in vanilla javascript only. Thanks in advance.

Taylor Kay
  • 59
  • 5

2 Answers2

1

You can use recursive function like so:

function getPath(obj, path) {

    var props = [];    

    for(var key in obj) {

        if(obj[key] === undefined) {
            props.push(path + '.' + key);
        }

        if(obj[key] instanceof Object) {
            props.push.apply(props, getPath( obj[key], path + '.' + key ));
        }

    }

    return props;
}


var path = getPath(dog, 'dog');

This will return an Array of paths to undefined properties

You can use join on resulting 'Array' to get String if necessary:

console.log(path.join('\n'));
Artem Petrosian
  • 2,946
  • 1
  • 20
  • 30
  • Thanks, Artem! Thanks to the comments above as well, I did a similar solution to yours (not using `apply` but rather and using `typeof` instead of `instanceof`). – Taylor Kay May 30 '15 at 19:53
  • 1
    @TaylorKay you are welcome, but FYI `instanceof` is more safer way in case of you have arrays in your object properties `typeof([])` will return `"object"` as well – Artem Petrosian May 30 '15 at 19:55
0

We now use object-scan for data processing like that. Just so hard to reinvent the wheel every time. Here is how it would work

// const objectScan = require('object-scan');

const find = (data) => objectScan(['**'], {
  joined: true,
  filterFn: ({ value }) => value === undefined
})(data);

const dog = { name: 'Max', age: 5, sex: undefined, details: { color: 'black', breed: undefined } };

console.log(find(dog));
// => [ 'details.breed', 'sex' ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>

Disclaimer: I'm the author of object-scan

vincent
  • 1,290
  • 1
  • 11
  • 19