1

I'm trying to read in data from a csv and form a map with key = state abbreviation and value = the frequency of that state in the data.

The code I have correctly creates a map and reads in the data, and I can console.log(MAP) correctly.

However, when I try to iterate through the map using .each or .entries(), the map is empty. map.size() returns 0.

var statesData = d3.map();
d3.csv("temp-data.csv", function(error, data) {
    if (error) throw error;
    data.forEach(function(row) {
        if (statesData.has(row.state) == false) {
          statesData.set(row.state, 1);
        }
        else {
          statesData.set(row.state, statesData.get(row.state) + 1);
        }
    });
});
console.log(statesData);
console.log(statesData.size());
statesData.each(function(d) {
  console.log("value: " + d);
});

Output:

{}
"$AZ": 1
​
"$CA": 1
​
"$CO": 1
​
"$IA": 1
​
"$KS": 2
​
"$OK": 1
​
"$OR": 1
​
"$PA": 1
​
"$WA": 1
​
<prototype>: Object { constructor: Map(), has: has(), get: get()
, … }
0

enter image description here A picture is also attached for clarification.

temp-data.csv:

id,state,
3,WA
4,OR
5,KS
8,CA
9,CO
11,OK
13,AZ
15,KS
16,IA
17,PA

So it seems as though the map has data within it, but when I call .size() it returns 0 (which explains why the .each() method doesn't show any output.

I honestly don't understand why this is occurring. I tried reading the docs https://devdocs.io/d3~4/d3-collection#map but it don't understand why I can console.log(MAP) fine but not iterate through it.

Thank you!

1 Answers1

1

Got it:

variable scope in d3 javascript

The d3.csv is an asynchronous request, so all code that depends on the data provided by that function should be within that scope.

This explains why the size of statesData outside of the d3.csv scope is 0.

The following:

var statesData = d3.map();
d3.csv("temp-data.csv", function(error, data) {
    if (error) throw error;
    data.forEach(function(row) {
        if (statesData.has(row.state) == false) {
          statesData.set(row.state, 1);
        }
        else {
          statesData.set(row.state, statesData.get(row.state) + 1);
        }
    });

    console.log(statesData.size())
});

Correctly outputs 9.