I cannot get multiple files to load data and assign to globals. I've read up on similar questions and related examples, but I still am having trouble.
var origins = [],
geoJSON = {
"type": "FeatureCollection",
"features": []
};
queue(1)
.defer(d3.csv, "path_to.csv", function(d) {
origins.push(d.o_geoid)
})
.defer(d3.json, "path_to.json", function(d) {
// Limit GeoJSON features to those in CSV
for (var i = d.features.length - 1; i >= 0; i--) {
if($.inArray(d.features[i].properties['GEOID10'], origins) != -1) {
geoJSON.features.push(d.features[i]);
}
}
})
.await(ready);
function ready() {
console.log(geoJSON);
}
I'm happy to filter the geoJSON features within ready() if that works better, but I need it to happen before I start creating the map with
d3.g.selectAll("path")
.data(geoJSON.features)
.enter.append("path")
...
I'm assuming this has to do with callbacks and empty results, but I can't quite get it working. I have figured out that using .await(console.log(geoJSON)); outputs the correct object to the console. The ready() function won't execute though. Thanks for any help understanding and fixing this problem.
Your question was already answered by Jason Davies' reply to the thread you linked but anyway, here it is re-stated in terms of your exact example...
I've never used queue but, if you think about it, it's pretty obvious from Jason's answer how it works.
The basic pattern is
The call signature for the first argument of
.deferisfunction(url, callback)and signature of the callback isfunction(error, result). The former is aligned with d3 conventions (for which queue is obviously designed) and the later is asynchronous javascript (i.e. node) conventional practice.To make this work, under the hood, queue needs to provide the callback argument, and that needs to be a function that hits the
awaitobject, with the result of the asynch request as arguments, using the standardfunction(error, result)signature.If you use the direct pattern, where the first argument of defer is
d3.csvfor example, then, after it completes,d3.csvwill invoke the callback provided by queue, therefore connecting with theawaitobject, passing it's error/result state.In the indirect pattern described by Jason Davies,
d3.csvis wrapped in another function - with the same signature - that defers invocation of the internally provided queue callback, until afterd3.csvhas completed and your post-processing is done.Now that we understand what's going on, we can think about refactoring to make it cleaner. Perhaps like this...
...which has exactly the same effect.