I'm using d3.json
to load a JSON file containing my data, like this:
var data = d3.json(url, callback)
If I do a console.log(data)
I can see that data
is neither empty nor null
. However, it doesn't seem to contain my data array, but something else instead.
What am I doing wrong here?
Note: this is a self-answered question, trying to provide a "canonical" Q&A on a subject that has been touched on by many previous questions and not (clearly) explained by the API. The answer below was written as a general guidance to those questions.
TL;DR
d3.json
(as well as d3.csv
, d3.tsv
etc) does not return the content of the loaded/parsed file. Instead of that, it returns an object related to the request (caveat, lector: this answer only applies to D3 v3 and v4, but not to v5, since D3 v5 uses promises).
What does d3.json return?
d3.json
is one of the alternatives to XMLHttpRequest
provided by D3. According to the API, d3.json
...
Returns a new request to get the JSON file at the specified url with the default mime type application/json.
... which, we can agree, is not particularly clear. Because of that, you probably thought that you could return the loaded data using var data = d3.json(url, callback)
, but that's incorrect. What d3.json
returns is an object (not an array), associated with the request. Let's see it.
I have this JSON in a file:
[{
"name": "foo",
"value": 42
}, {
"name": "bar",
"value": 12
}, {
"name": "baz",
"value": 34
}]
What happens if we use d3.json
the way you used it in your question? Click "run code snippet" to see:
var data = d3.json("https://api.myjson.com/bins/k4xqn", function() {});
console.log(data)
<script src="https://d3js.org/d3.v4.min.js"></script>
As you can see in the console, we have an object like this:
{header: ƒ, mimeType: ƒ, responseType: ƒ, timeout: ƒ, user: ƒ, …}
Well, this is not our data array.
The same thing happens if you use a function:
function getData() {
return d3.json("https://api.myjson.com/bins/k4xqn", function() {})
}
var data = getData()
console.log(data)
<script src="https://d3js.org/d3.v4.min.js"></script>
Also, it's worth mentioning that the same thing happens with d3.csv
, d3.tsv
and the other request methods:
var data = d3.csv("https://www.ibm.com/support/knowledgecenter/SVU13_7.2.1/com.ibm.ismsaas.doc/reference/AssetsImportCompleteSample.csv", function() {});
console.log(data)
<script src="https://d3js.org/d3.v4.min.js"></script>
How to use d3.json?
The correct way to load the data with d3.json
, as you can see in several online examples, is using its callback:
d3.json(url, function(data){
//use data here...
});
And here is the snippet with our JSON file:
d3.json("https://api.myjson.com/bins/k4xqn", function(data) {
console.log(data)
})
<script src="https://d3js.org/d3.v4.min.js"></script>
You can also call another function: the data will be passed as the first argument. Here is a demo:
d3.json("https://api.myjson.com/bins/k4xqn", callback)
function callback(data) {
console.log(data)
}
<script src="https://d3js.org/d3.v4.min.js"></script>