0


I have a view-request which returns amount X and will then fire a function X times through a for-loop. It works everything but due to the asynchronous request, I do not get the correct i-value that the function/request was fired with. The (javascript) code:

X = [0,2,4,6]
for(var i = 0; i < X.length; i++) {
    // i is the user ID
    contract.getUser(i, function (err, result) {
        if (err) {
        /////
    }
    else if (result) {
            // I want to return the current i-value (loop-value),
            // But due to the asynchronous request, it always returns the 
            // last value (in our example 4)
            console.log(i);
        }
    }
}

Everything works fine (I get the user) but I can't redirect to for example url.com/user/ID because the ID (i) is always the same.

Thanks for help!

1

The issue is that the same i is being captured by all the callback functions, so they all see the same value when they're ultimately invoked.

One popular workaround is to use an immediately invoked function expression (IIFE) as follows:

X = [0,2,4,6]

for (var i = 0; i < X.length; i++) {
    (function (n) { // function is defined here
        contract.getUser(n, function (err, result) {
            if (err) {
                ...
            }
            else if (result) {
                console.log(n);
            }
        });
    })(i); // and immediately executed here, with a specific i value passed in
}
2
  • Thank you, that works! contract.getUser(i..) even works, I just can't work with it as the result is showed only later. But this solved it! – dkb Apr 22 '19 at 18:22
  • Yes, i in the call to getUser is fine because it happens synchronously (so it receives the current value of i for that iteration of the loop). It's just the callback that's problematic because it sees the current value of i at that time, which is after the loop has finished. – user19510 Apr 22 '19 at 18:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.