Skip to content

Instantly share code, notes, and snippets.

@elog08
Created January 31, 2017 02:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elog08/fed1b7924e98e324c241e3505423ebbd to your computer and use it in GitHub Desktop.
Save elog08/fed1b7924e98e324c241e3505423ebbd to your computer and use it in GitHub Desktop.
A recursive function to process nested JSON objects asynchronously
/*
* Modifies the values of a JSON object recursively and asynchronously.
*/
// Wrapper for async.Map that persists the keys of the object
// https://github.com/caolan/async/issues/374#issuecomment-59191322
async.objectMap = async.objectMap || function(obj, func, cb) {
var i, arr = [],
keys = Object.keys(obj);
for (i = 0; i < keys.length; i += 1) {
arr[i] = obj[keys[i]];
}
async.map(arr, func, function(err, data) {
if (err) {
return cb(err);
}
let res = {};
for (i = 0; i < data.length; i += 1) {
res[keys[i]] = data[i];
}
return cb(err, res);
});
}
// Async recursive function
let recurse = function(obj, mutator, done, isChild) {
// If it has children, loop through each
if (typeof obj === 'object') {
async.objectMap(obj, (child, _done) => {
// If child is object, recurse
if (typeof child === 'object') {
recurse(child, mutator, _done, true);
} else {
mutator(child, _done);
}
}, (err, finalObj) => {
// Reached root level
done(err, finalObj);
});
} else {
// Misguided call, no children here...
done(null, obj);
}
}
let mutator = function(val, cb) {
// Async operation, could be an AJAX call...
return setTimeout(() => {
// Transform all values to lower case
cb(null, val.toString().toLowerCase());
}, 2000);
}
// Generated with: http://schematic-ipsum.herokuapp.com/
let testObj = {
"name": "Mike Anderson",
"children": [{
"name": "D'Lo Brown",
"bio": "The 1949 Ambato earthquake initially followed an intersection of several northwest-southeast-trending faults in the Inter-Andean Valley, which were created by the subduction of the Carnegie Ridge.",
"age": -63
}],
"email": "aljin_abella@on.org",
"bio": "As it was, one Member of Parliament wrote: \"Except the cut in the lower part of the ear I think there was no injury done worth mentioning."
};
recurse(testObj, mutator, function(err, obj) {
if (err) {
return console.error(err);
}
let prettyJSON = JSON.stringify(obj, '\t');
document.getElementById('output').innerHTML = prettyJSON;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment