1

So in d3 I want an array for functions such that

var data = [44,23];
var line = [];
for (var i = 0; i < data.length; i++) {
    line[i] = d3.svg.line()
           .interpolate("monotone")
           .y(function(d) {
                return data[i];               
            });
}

However, because of the way the closure works, the i is always evaluated to 2. Is there a way to make it evaluate as 0, then 1, instead of 2 always?

Gargob
  • 251
  • 4
  • 14
  • Just ran your code on jsfiddle, with d3.js pasted in the source. i evaluates to 0, 1. What do you mean by "because of the way the closure works"? – lesssugar Aug 07 '14 at 22:58
  • Later when I need to call line[0]() or line[1](), it will basically call return data[2]; – Gargob Aug 07 '14 at 23:01
  • We would need to see more code. From what you're saying, data[2] would return `undefined`, as it has only 2 elements. – lesssugar Aug 07 '14 at 23:04
  • See [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/q/750486/218196) – Felix Kling Aug 07 '14 at 23:28

1 Answers1

4

If your inline function being passed into y is being called asynchronously, i will be equal to data.length when it is called. To avoid this, you can simply use the array forEach method like so:

var data = [44,23];
var line = [];
data.forEach(function(dataItem, i) {
    line[i] = d3.svg.line()
       .interpolate("monotone")
       .y(function(d) {
            return dataItem;               
        });
});
SimpleJ
  • 13,812
  • 13
  • 53
  • 93