0
for (i = 0; i < roles.length; i++) {
    Permission.defineRole(roles[i], function () {
        console.log(roles[i]);
    });
}

variable i is undefined.

How to get thats values?

Tushar
  • 85,780
  • 21
  • 159
  • 179
Donny Gunawan
  • 363
  • 1
  • 6
  • 21
  • Use [`bind`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) – hindmost Sep 08 '15 at 09:20
  • 1
    are you sure that _undefined_ is `i` variable and not `roles[i]`? – Grundy Sep 08 '15 at 09:20
  • possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) – Grundy Sep 08 '15 at 09:21
  • `i` is definitely **not** undefined in that code snippet - if the anonymous function is an asynchronous callback, you'll have other issues, like i being roles.length in the console.log statement, and therefore `roles[i]` is by definition guaranteed to be undefined ... but `i` is not the undefined variable – Jaromanda X Sep 08 '15 at 09:22

3 Answers3

1

Try this:

function executeCallback(role) {
    Permission.defineRole(role, function () {
        console.log(role);
    }
}
for (var i = 0; i < roles.length; i++) {

    executeCallback(roles[i]);
}

At the moment of execution of the callback, i might have changed (if the callback executes asynchcronously). Also as others noticed, you should add the keyword var (though that doesnt cause the undefined).

EricG
  • 3,788
  • 1
  • 23
  • 34
  • also a way to avoid the issue of closures. I prefer doing this in the way the callback is run (see my answer) but this is perfect if you can't actually control the code running the callback from defineRole (in case it's a 3rd party library) – Ward D.S. Sep 08 '15 at 09:37
0

Can you change the definition of how your callback is executed? You might want to call your callback with the role parameter given, to avoid these closure issues.

Permission.defineRole = function(role, callback){
 //do stuff with your role
 //...

 //when you run the callback, add the role from this closure
 callback(role);
}

and then

for (i = 0; i < roles.length; i++) {
    // pass the roles[i] value to the new function, which creates a new scope for this iteration
    Permission.defineRole(roles[i], function (role) {
        // because role was passed down from the defineRole scope particular to that iteration, role is now the correct one, and different from roles[i].
        console.log(role);
    });
}

That said, if roles[i] is ever undefined, i probably isn't a value between 0 and the length of your array, or you simply assigned undefined to that key in the array.

It is also likely other code is changing i at the same time, since you did not use the var keyword to declare it (it's now on your global window object). Please use strict mode and use var to declare all variables, and window.name to add variables to the window object.

Ward D.S.
  • 536
  • 3
  • 11
-4

If you use strict mode, you MUST to declare the variable by keyword var.

Wrong code:

function d() {
    'use strict';
    asdf = 1;
}

Correct codes:

function d1() {
   'use strict';
    var asdf = 1;
}

function d2() {      
    asdf = 1;
}
Fenex
  • 239
  • 1
  • 8
  • the code wouldn't even run (it should throw an error in the parser) if you hadn't declared a variable in strict mode. – Ward D.S. Sep 08 '15 at 09:32
  • @WardD.S. i tried to exec first function into console, and all right. but if execute the function, console shown the error `asdf is not defined`. – Fenex Sep 08 '15 at 09:38
  • Mh I was wrong about throwing a parse error, but it still errors if you try to assign an undefined variable in strict mode, which proves that the OP is either not in strict mode, or already declared `i` somewhere else, since his code runs (but with unexpected results). It's a good remark that he should use strict mode, but it isn't the cause of his issue. – Ward D.S. Sep 08 '15 at 09:45
  • @WardD.S. He's code don't catch exception `variable i is undefined`.The code should view into the console the same object (roles.length times)... isn't it? – Fenex Sep 08 '15 at 09:57