Reputation: 833
I am currently learning how to use NodeJS and wrote this relatively simple function to run at a fixed interval. The aim of this function is to retrieve newly created Droplets and update their IP addresses.
router.newDroplets = setInterval(function() {
Server.find().then(function(svrs) {
for (var i = 0; i < svrs.length; i++) {
if (svrs[i].status == "Creating") {
library.getDropletById(svrs[i].serverid).then(function(svr) {
if (svr.droplet) {
for (var j = 0; j < svr.droplet.networks.v4.length; j++) {
if(svr.droplet.networks.v4[j].type == 'public') {
var ip_address = svr.droplet.networks.v4[j].ip_address;
console.log(ip_address);
Server.update({serverid: svr.droplet.id}, {ipaddress: ip_address, status: "Online"}, function(error, n) {
if (error) console.log(error);
else console.log(n);
});
}
}
} else if (svr.id) {
// NOTE THIS LINE
console.log(svrs);
}
}, function() {
});
}
}
}, function() {
});
}, 2500);
The peculiar behaviour is with the line marked above.
When I use console.log(svrs)
, I get an array of JSON documents in the Server collection in my MongoDB. However, when I use console.log(svrs[i])
, undefined
is logged in the console. This happens even if I declare var i = 0;
outside the for loop. Why is this happening and how can I access svrs[i]
?
Upvotes: 0
Views: 74
Reputation: 17957
The way promises work is that the promise chains run asynchronously. By the time that code runs, i
is equal to svrs.length
, so svrs[i]
will be undefined
. That's because the for loop executes in its entirety before any of the then
callbacks are called. You could convert your code to use Array.prototype.forEach
So you can try something like
svrs.forEach(function(svrInstance, i) {
if (svrInstance.status == "Creating") {
library.getDropletById(svrInstance.serverid).then(function(svr) {
if (svr.droplet) {
...
} else if (svr.id) {
console.log(svrs[i]);
}
});
}
});
Upvotes: 2