0

I have a for loop for running some iterations of javascript code and a function within that For Loop. The problem is that the function within my loop isn't receiving the index integer. Here is the code:

for (var i = 0; i < ToggleCount; i++) {
    ToggleFolder[i] = gui.addFolder(ToggleDescription[i]);
    ToggleChange[i] = { Status: false, Auto: false };
    ToggleStatus[i] = ToggleFolder[i].add(ToggleChange[i], 'Status', false).listen();
    ToggleAuto[i] = ToggleFolder[i].add(ToggleChange[i], 'Auto', false).listen();
    ToggleStatus[i].onFinishChange(function (value, i) {
        console.log(i);
        $.ajax({
            url: 'StatusUpdate.php',
            type: 'get',
            data: 'ToggleDevice=' + ToggleDescription[i] + '&val=' + value,
            success: function (result) { }
       });
       console.log(ToggleDescription[i]);
    });

    ToggleFolder[i].open();
}

The problem is that the console.log command is saying that "i" is undefined when it gets within the function. What is my problem?

Bic
  • 3,141
  • 18
  • 29
  • your callback defines "i" within that function, so "i" will be whatever your callback gets passed as a 2nd argument. you might want to rename it to avoid the ambiguity of what "i" means for that section... You might also have a problem trying to close "i" in the for loop, and for that you can use an anon wrap as has been show on here ad-nauseum. – dandavis Feb 09 '14 at 21:50
  • for private "i"s, you can replace the for loop with a forEach: String(Array(ToggleCount)).split(",").forEach(function(x,i){, which will fix a problem where every callback sees "i" as the max value. – dandavis Feb 09 '14 at 21:58

2 Answers2

0

You are seeing a problem, because you are declaring a function that accepts two parameters: value and i. As a result of this function declaration, you are clobbering the original value of i. In the context of the execution, i is already known, and does not need to be listed as a parameter:

for (var i = 0; i < ToggleCount; i++) {
    ToggleFolder[i] = gui.addFolder(ToggleDescription[i]);
    ToggleChange[i] = { Status: false, Auto: false };
    ToggleStatus[i] = ToggleFolder[i].add(ToggleChange[i], 'Status', false).listen();
    ToggleAuto[i] = ToggleFolder[i].add(ToggleChange[i], 'Auto', false).listen();
    ToggleStatus[i].onFinishChange(function (value) {
        console.log(i);
        $.ajax({
            url: 'StatusUpdate.php',
            type: 'get',
            data: 'ToggleDevice=' + ToggleDescription[i] + '&val=' + value,
            success: function (result) { }
       });
       console.log(ToggleDescription[i]);
    });

    ToggleFolder[i].open();
}
Bic
  • 3,141
  • 18
  • 29
0

Your first problem is that you redefine i as parameter for your function, which overwrites the i from your for-loop. By removing that parameter you now can reference that inside the function:

for (var i = 0; i < ToggleCount; i++) {
    ToggleFolder[i] = gui.addFolder(ToggleDescription[i]);
    ToggleChange[i] = { Status: false, Auto: false };
    ToggleStatus[i] = ToggleFolder[i].add(ToggleChange[i], 'Status', false).listen();
    ToggleAuto[i] = ToggleFolder[i].add(ToggleChange[i], 'Auto', false).listen();
    ToggleStatus[i].onFinishChange(function (value) {
        console.log(i);
        $.ajax({
            url: 'StatusUpdate.php',
            type: 'get',
            data: 'ToggleDevice=' + ToggleDescription[i] + '&val=' + value,
            success: function (result) { }
       });
       console.log(ToggleDescription[i]);
    });

    ToggleFolder[i].open();
}

Now you will run into another problem though: when the onFinishChange function is called, the i variable will have changed already (probably it will be equal to the length of the array), so your index will be wrong. To fix that, you have to create an immediate function to capture the value:

for (var i = 0; i < ToggleCount; i++) {
    ToggleFolder[i] = gui.addFolder(ToggleDescription[i]);
    ToggleChange[i] = { Status: false, Auto: false };
    ToggleStatus[i] = ToggleFolder[i].add(ToggleChange[i], 'Status', false).listen();
    ToggleAuto[i] = ToggleFolder[i].add(ToggleChange[i], 'Auto', false).listen();
    ToggleStatus[i].onFinishChange((function(index){
        return function (value) {      
            console.log(index);
            $.ajax({
                url: 'StatusUpdate.php',
                type: 'get',
                data: 'ToggleDevice=' + ToggleDescription[i] + '&val=' + value,
                success: function (result) { }
           });
           console.log(ToggleDescription[index]);
    })
    })(i));

    ToggleFolder[i].open();
}
Kenneth
  • 28,294
  • 6
  • 61
  • 84