Reputation: 1724
I'm doing a pretty trivial thing in D3, but I'm running into weird issues with the order of code execution. I'm taking an array of image names, looping through them, and adding each svg
to a parent svg
as a g
element. All that works great. Here's the code that's doing so:
var names = ['a', 'b', 'c']
var over = d3.select('#overlay');
var w = 20;
for (var i = names.length - 1; i >= 0; i--) {
var x = w * i + w
console.log('1. '+ x)
d3.xml(names[i]+'.svg', function(error, xml) {
console.log('2. '+ x)
over.append('g')
.attr('transform','translate('+ x +','+ 20 +')')
.html(xml.getElementsByTagName('svg')[0].innerHTML)
})
}
However, I'm running into issues with the transforms all being the same, and decided to log x to check it out. The log should be this:
1. 60
2. 60
1. 40
2. 40
1. 20
2. 20
Instead, it's logging this:
1. 60
1. 40
1. 20
2. 20
2. 20
2. 20
What could possibly be making this run out of order like that?? Is the d3.xml
call asynchronous? I can't figure it out.
Upvotes: 1
Views: 294
Reputation: 11258
d3.xml()
is asynchronous function and is not started in sequence as expected but little later which is enough that loop is over and x
has value 20.
You have to make closure for value x
using for example:
(function (x) {
d3.xml(names[i]+'.svg', function(error, xml) {
console.log('2. '+ x)
over.append('g')
.attr('transform','translate('+ x +','+ 20 +')')
.html(xml.getElementsByTagName('svg')[0].innerHTML)
});
})(x)
That way you will get in console log:
1. 60
1. 40
1. 20
2. 60
2. 40
2. 20
Upvotes: 2