Problems with dataset for D3 Bar Chart

Tell us what’s happening:
I’m working on D3 Bar Chart project and I extracted the array with the needed data from json file provided with the challenge. I saved the array into the variable named ‘dataset’. When trying to use the dataset in a d3 query (just for testing it), it appears that the dataset array is empty, however, with console.log the array contents are successfully printed to the browser console. I could not figure the reason why this is happening.

Your code so far

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://d3js.org/d3.v6.js"></script>
    <link rel="stylesheet" href="styles.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
    <link rel="preconnect" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300&display=swap" rel="stylesheet">
    <title>D3 Bar Chart</title>
</head>
<body>
    <div id="chart-container">
        <h1 id="title">United States GDP</h1>
    </div>
    <script>
        let dataset = [];
        const w = 500;
        const h = 500;

        fetch('https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json').then(
            response => response.json()).then(
            data => {
                for(let i = 0; i < data.data.length; i++) {
                    dataset.push(data.data[i]);
                }


            });

        d3.select('#chart-container').selectAll('p').data(dataset).enter().append('p').text((d) => d[1]);
        
    </script>
</body>
</html>

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36.

Challenge: Visualize Data with a Bar Chart

Link to the challenge:

try d3 query in another then block.

Add

console.log(dataset);
console.log(dataset.length);

before

and you’ll see that dataset has a length of zero. D3 expects an array with a non-zero length or it won’t append any elements. It looks like your loop in your fetch() is creating dataset with a reference (since data.data[i] is an array and you’re not destructuring) and not an actual array. You may want to do some preprocessing and convert the raw data points into objects and then push them onto dataset.

It changes nothing…

This way I think I will obtain an array of objects, isn’t there a way to extract dataset as a simple bidimensional array, and access it with indexes?

fetch is async. Try moving the code below inside the callback just after populating dataset.

 d3.select('#chart-container').selectAll('p').data(dataset).enter().append('p').text((d) => d[1]);
        

Thanks a lot! :+1: Now it works, I refactored the code as follows:

        fetch('https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json').then(
            response => response.json()).then(
            data => {
                for(let i = 0; i < data.data.length; i++) {
                    dataset.push(data.data[i]);
                }
      
                d3.select('#chart-container').selectAll('p').data(dataset).enter().append('p').text((d) => d[1]);

            });
1 Like

As usual, it’s the async. This is the right solution.

What gets me, is that sometimes (like this) console.log() will spit out the data and then the statement right after will not work, which apparently I have not bothered to research before (one, two) despite having encountered this problem before and working around it. So that others may benefit from my mistake, I suggest being very careful using console.log() to debug a problem that may be asynchronous in nature.

And to top it off, I was just thinking that there should be a big warning flag about using console.log() on objects and there is, but MDN expects me to read about the simple and obvious console.log() all the way to the Specifications and Browser Compatibility sections to get this tidbit.

Oh well. Happy St Patrick’s Day.