How to iterate through nested JSON values ​​using async.js

advertisements

I'm relatively new to nodeJS/Javascript's asynchronous nature (Python background) and trying am trying to figure how to step through a nested JSON object, extract it's values using asnyc.js.

I came across this snippet, How to navigate in nested JSON.

function recursiveGetProperty(obj, lookup, callback) {
    for (property in obj) {
        if (property == lookup) {
            callback(obj[property]);
        } else if (obj[property] instanceof Object) {
            recursiveGetProperty(obj[property], lookup, callback);
        }
    }
}

Which works great with this sample object, foo.

var foo = {
  'key_1' : 'val1',
  'key_2': {
    'key_3': 'val3',
    'key_4': 'val4'
  }
}

recursiveGetProperty(foo, 'key_1', function(obj) {
  console.log(obj);
});

returns 'val1'

recursiveGetProperty(foo, 'key_3', function(obj) {
  console.log(obj);
});

returns 'val3'

This is exactly what I needed but when I feed it key values via iteration:

var keys = ['val1', 'val3'];

for (var keys in keys) {
  recursiveGetProperty(foo, keys, function(obj) {
    console.log(obj);
  });
}

nothing is logged to console. so I wrote a logging function:

function log(obj) {
  console.log(obj);
}

and tried:

for (var key in keys) {
  recursiveGetProperty(foo, keys, log(obj));
}

but i get ReferenceError: obj is not defined.

I was told it's not a great idea to execute a callback inside a for loop, I'm not exactly sure why so I looked into async.js. It seems like the right solution for what I want but I have no idea how to go about it.

Using async.js, I would like to build a series of recursiveGetProperty functions, store them in an array, and then execute those calls asynchronously but I'm stumped on how to approach the problem.

What I would ultimately want is something like this:

async.each(['key_1', 'key_2', 'key_3'], recursiveGet(key) {
  doSomethingWithData();
}, function(err) {
  doSomethingWhenDone();
});

This would be used on an ExpressJS server to parse JSON and do something with it afterwards.

Any help or suggestion would be greatly appreciated.


There are bug in this code

var keys = ['val1', 'val3'];
for (var keys in keys) {
    recursiveGetProperty(foo, keys, function(obj) {
        console.log(obj);
    });
}

  • The array of keys (line 1) is overwritten by the keys index (line 2) of the for loop. So let's rename that key.
  • For an iterated array a key would be a number (0, 1, ..., n), not a string. You need to use those numbers as indices to keys
  • Also your recursiveGetProperty finds by keys not values.

So the code should be

var keys = ['key_1', 'key_2'];
for (var key in keys) {
    recursiveGetProperty(foo, keys[key], function(obj) {
        console.log(obj);
    });
}