svg.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.enter().append("path")
.attr("d", path)
.append("title")
//NOTE: d.id === fips. Need to make a function to match these. d.id is NOT in ascending order.
//Notice that the numbers do not match.
//.text((d, i) => (d.id + ' and ' + json[i].fips))
//For loop attempt, which broke everything:
// .text((d, i) => (
// for(var k=0; k<json.length; k++){
// d.id === json[k].fips ? return json[k].area_name : return "odd";
// }
// )
Your browser information:
User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36.
line 1: you don’t need i as you aren’t using it in your code. Technically it isn’t breaking your code but it is redundant. Fix: remove i.
line 1: you have an opening parenthesis after =>. And no closing parenthesis by the way - but it’s not important in this case as you should’t use parenthesis here at all. Rather you should be using curly braces when writing arrow functions. As you have more than one line in your arrow function body you need braces around to signify a new block that allows for multiple statements. Without braces, the arrow function can only execute one line. Fix: remove opening parenthesis and surround block with curly braces.
line 3: the syntax of your ternary operator is incorrect. It should look like this condition ? expression1 : expression2 and in your code it looks like this condition ? statement1: statement2. The conditional operator requires expressions, not statements. return is a statement. Fix: remove both return statements from your ternary operator and add return statement in front of ternary operator like so: return condition ? expression1 : expression2.
Now let’s look together what our corrected ternary operator is returning:
Setting text for tooltip of first county:
first loop iteration:
sets k to 0
checks if d.id === json[0].fips
returns "odd" as d.id === json[0].fips evaluates to false
It will NOT continue to loop because of the return statement. The return statement stops the execution and returns a value.
The same goes for other counties too - all counties but one will get tooltip with text “odd”.
And only one county will get desired tooltip (as only one time d.id === json[0].fips will evaluate to true).
At this point you can hover over your map and see the tolltips. All display text “odd” and only one displays correctly “Autauga County”.
The problem (as we already determined) is return statement which breaks us out of the loop prematurely. Rewriting our ternary operator to an if statement would help:
.text(d => {
for(var k = 0; k < json.length; k++) {
if (d.id === json[k].fips) {
return json[k].area_name;
}
}
return "odd";
})
Setting text for tooltip of first county:
first iteration:
sets k to 0
checks if d.id === json[0].fips which evaluates to false
loop goes to next iterations:
until d.id === json[k].fips evaluates to true (return json[k].area_name)
or loop has gone through all education file and didn’t found matching id (return "odd").
Alternative solution - you could use filter function instead of for loop as it might be easier to read:
First you filter out json array. Now result variable stores either an empty array (if filter function couldn’t find matching ids) or an array with one object (if filter function did find matching ids).
Next I am using ternary operator to check if result is an empty array (result[0] evaluates to false) or not (result[0] evaluates to true).
I wrote a lot so if you find something confusing - ask away