GJain
GJain

Reputation: 5093

javascript: getting incorrect variable being set when passed as an argument

I have following code & output. I don't understand why the function is receiving incorrect argument. Please provide pointers.

var tempAccounts = [];
var i;
for (i = 0; i < accountIDs.length; i++) {
    var accountID = accountIDs[i];
    console.log("Log1:" + accountID);
    tempAccounts.push(function(callback){createTempAccount(accountID, callback)})
}

async.parallel(tempAccounts, function (error, results) {
    if (error) {
        sendError(error, "error creating temp acounts", res, logTag);
    } else {
        res.set('Content-Type','application/json');
        res.send(200, {});
    }
});


function createTempAccount(accountID, callback)
{
  console.log("Log2:" + accountID);
  ...
}

Output:

Log1: 1234
Log1: abcd

Log2: 1234
Log2: 1234

What could be the issue here?

Upvotes: 0

Views: 49

Answers (1)

Mark
Mark

Reputation: 92440

You don't need all the extra code to see the problem. It can be reduced to the following snippet. When you defined the function in the loop you capture the a shared variable in a closure. Then later when you call those functions, you get just the one value:

var tempAccounts = [];
let accountIDs = [200, 400]
var i
for ( i = 0; i < accountIDs.length; i++) {
    var accountID = accountIDs[i];
    console.log("Log1:" + accountID);
    tempAccounts.push(function(){return accountID})
}
// all the same value
console.log(tempAccounts.map(i => i()))

The easiest way to deal with this is using let to define a new variable in each iteration of the loop:

var tempAccounts = [];
let accountIDs = [200, 400]
for (let i = 0; i < accountIDs.length; i++) {
    let accountID = accountIDs[i];
    console.log("Log1:" + accountID);
    tempAccounts.push(function(){return accountID})
}

// now you get the unqie values:
console.log(tempAccounts.map(i => i()))

Upvotes: 1

Related Questions