Reputation: 193
I've been using d3.js v4 for sometime now and I've learned that Mike Bostock has replaced the d3.queue in the v5 release with the Promise native JavaScript object. I would like to check with you if this code that I have written is properly queuing (asynchronously) these URL's:
var makeRequest = function() {
"use strict";
var bli = [
"http://stats.oecd.org/sdmx-json/data/BLI2013/all/all",
"http://stats.oecd.org/sdmx-json/data/BLI2014/all/all",
"http://stats.oecd.org/sdmx-json/data/BLI2015/all/all",
"http://stats.oecd.org/sdmx-json/data/BLI2016/all/all",
"http://stats.oecd.org/sdmx-json/data/BLI/all/all"
];
var promises = [];
bli.forEach(function(url) {
promises.push(
new Promise(function(resolve, reject) {
d3
.json(url)
.then(function(response) {
resolve(response);
})
.catch(function(error) {
console.log("Error on: " + url + ". Error: " + error);
reject(error);
});
})
);
});
Promise.all(promises).then(function(values) {
console.log(values);
});
};
makeRequest();
The code seems to function properly, but, is this proper code or is there a better way (a best practice approach) for queuing with Promise.all and d3.js? Is the catch error properly implemented?
Upvotes: 17
Views: 15188
Reputation: 61
You can also add a formatting function for your data as such if you want to clean up your data to your preference. .then() will have your data in a nice array which you can use later.
const myData = d3.csv("data.csv", formatterFunction)
.then(data => /* do whatever*/ )
function formatterFunction(row){
// do formatting
return // formatted data
}
Upvotes: 0
Reputation: 7162
Here's an approach with ES6 async functions and ES6 array destructuring:
async function chart() {
const [first, second] = await Promise.all([
d3.json('data1.json'),
d3.json('data2.json'),
])
console.log('data2.json :', second)
}
chart()
Upvotes: 1
Reputation: 102198
You can simplify that code a lot: you don't net to use new Promise
with d3.json
, since d3.json
will itself create the promise.
So, you can just do:
var files = ["data1.json", "data2.json", "data3.json"];
var promises = [];
files.forEach(function(url) {
promises.push(d3.json(url))
});
Promise.all(promises).then(function(values) {
console.log(values)
});
Or, if you're into the code golf, even shorter:
var files = ["data1.json", "data2.json", "data3.json"];
Promise.all(files.map(url => d3.json(url))).then(function(values) {
console.log(values)
});
Since I cannot use JSON files in the S.O. snippet, check the console in this bl.ocks: https://bl.ocks.org/GerardoFurtado/f08993c9c729b0b3452ef1803ad9dcbf/c4b45c5acce6033085a667cbb7d34203d15de0f0
Upvotes: 27