4

I have the following code:

for (var i = 0; i < data.length; i++) {
        var file = data[i];
        $.getJSON("/types/" + file, function(json) {
            if (json[0] !== undefined) {
                console.log(json[0] + file);
            }
        });
    }

But my editor is saying "Mutable variable is accessible from closure". I've tried to change function(json) { to function(json, file) {, but this don't work because this is a default function of jquery.

I hope you can help my fixing the problem.

Jenz
  • 8,280
  • 7
  • 44
  • 77
jan
  • 142
  • 2
  • 2
  • 9

4 Answers4

19

For such loops, you need to put the contents in a closure.

for (var i = 0; i < data.length; i++) {
    (function(){
        var file = data[i];
        $.getJSON("/types/" + file, function(json) {
            if (json[0] !== undefined) {
                console.log(json[0] + file);
            }
        });
    })();
}
Van Coding
  • 24,244
  • 24
  • 88
  • 132
9

You can use a closure as suggested, also it doesn't make your code easier to read, especially if your closure is inside a loop! Much easier and cleaner to simply create a function and call it on each iteration.

for (var i = 0; i < data.length; i++) {
    doJson(data[i]);
}

function doJson(file) {
    $.getJSON("/types/" + file, function(json) {
        if (json[0] !== undefined) {
            console.log(json[0] + file);
        }
    });
}

Or you could simply update your loop to use forEach instead, because a new function get fired on each iteration the scope will be limited to it.

data.forEach(function(file) {

    $.getJSON("/types/" + file, function(json) {
        if (json[0] !== undefined) {
            console.log(json[0] + file);
        }
    });
});
GillesC
  • 10,647
  • 3
  • 40
  • 55
3

If you can use ES6, you could simply replace var with let and everything works as expected because let creates a new scope in every iteration of the for loop.

for (let i = 0; i < data.length; i++) {
        var file = data[i];
        $.getJSON("/types/" + file, function(json) {
            if (json[0] !== undefined) {
                console.log(json[0] + file);
            }
        });
    }
can.
  • 2,098
  • 8
  • 29
  • 42
2

You should use closure : ( be careful when running functions in a loop).

for (var i = 0; i < data.length; i++)
{
    var file = data[i];

    (function(f)
    {

        $.getJSON("/types/" + f, function(json)
        {
            if (json[0] !== undefined)
            {
                console.log(json[0] + f);
            }
        })
    })(file);


}
Royi Namir
  • 144,742
  • 138
  • 468
  • 792