I'm new to Nodejs, and I've been writing a Web3 handler for my contract, everything works good but the global variables don't update during the promise execution, they have no value even when I console.log after the Then.
...
var cityDb = {};
function gettingBalance() {
return new Promise ( (resolve, reject) => {
Contract.totalSupply.call(function(error, result){
if(!error)
{
resolve(result.toNumber());
}
else
reject(error);
});
});
}
function gettingCities(cityNumber) {
return new Promise ( (resolve,reject) => {
Contract.CityDB.call( cityNumber, (error, result) => {
if(!error)
{
resolve(result);
}
else
reject(error);
});
});
}
gettingBalance()
.then ( (result) => {
console.log('Total after function: '+result);
return result;
})
.then ( (totalSupply) => {
console.log('loop data :'+totalSupply);
// START SECOND PROMISE
for (let i=0; i <= totalSupply; i++) {
gettingCities(i)
.then( (result) => {
cityDb[i] = {
cityName: result[0],
Population: result[1],
};
let j = i-1;
console.log('Loop ['+i+']'+ cityDb[i].cityName);
})
.catch( (error) => {
console.log(error);
});
if (i == totalSupply) { return; }
}
// END SECOND PROMISE
})
.then ( (response) => {
console.log('Test promise loop: '+ cityDb[2]);
})
.catch( (err) => {
console.log('loop error: '+err);
});
Log results :
Total supply after function: 3
loop data :3
Test promise loop: undefined
Loop [0]0x4e657720596f726b000000000000000000000000000000000000000000000000
Loop [1]0x5061726973000000000000000000000000000000000000000000000000000000
Loop [2]0x4e61646f72000000000000000000000000000000000000000000000000000000
Loop [3]0x0000000000000000000000000000000000000000000000000000000000000000
Why is test promise loop undefined? The cityDB isn't getting update from the loop, but the loop works perfectly as intended.
The problem was that you weren't chaining promises correctly. Your last then
wasn't waiting until all your gettingCities
calls were done. For that you can use Promise.all
gettingBalance()
.then((result) => {
console.log('Total after function: ' + result);
return result;
})
.then((totalSupply) => {
console.log('loop data :' + totalSupply);
// START SECOND PROMISE
const promises = [];
for (let i = 0; i < totalSupply; i++) {
// We push gettingCities promises into the array
promises.push(gettingCities(i));
}
// We pass gettingCities promises into Promise.all
return Promise.all(promises);
})
.then((results) => {
// All gettingCities results
// We loop through each result and fill cityDb
results.forEach((result, i) => {
cityDb[i] = {
cityName: result[0],
Population: result[1],
};
console.log('Loop [' + i + ']' + cityDb[i].cityName);
})
console.log('Test promise loop: ' + cityDb[2]);
})
.catch((err) => {
console.log('loop error: ' + err);
});
You can remove the global cityDb
and just handle it in the last .then
.then((results) => {
// gettingCities results
const cityDb = {};
results.forEach((result, i) => {
cityDb[i] = {
cityName: result[0],
Population: result[1],
};
console.log('Loop [' + i + ']' + cityDb[i].cityName);
})
console.log('Test promise loop: ' + cityDb[2]);
})