Question

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.

Était-ce utile?

La solution

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);
    });
}

Autres conseils

var keys = ['key_1', 'key_2'];

keys.forEach(function (key) {
  recursiveGetProperty(foo, key, function(obj) {
    console.log(obj);
  });
});

http://jsfiddle.net/fPRQK/

Issues in your code:

  • for(var key in obj) works with object properties only, not with array values. Use Array.forEach or a regular for loop instead.
  • recursiveGetProperty(foo, keys, log(obj)): This would call log instantly and pass it's return value to recursiveGetProperty. You could either pass just log or function (obj) { log(obj); }, which in this case mean the same. Also in this case what you want to pass is key.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top