Reputation: 53
I know that javascript is asynchronous and if i make a for loop after .then
then the loop ends and only then do the object promise become clear, but I can't for the life of me fix this code snippet, maybe someone can help me. My goal is to loop and check if variable ans
, which I take from a function is equal to variable account
and if so then print out information that I get from other functions.
loopforCetrs : function() {
var num;
var account = web3.currentProvider.selectedAddress;
App.contracts.StudentState.deployed().then(function (instance) {
return instance.showNumOfContracts();
}).then(function (numOfCert) {
num = numOfCert;
var wrapper = document.getElementById("myHTMLWrapper");
for (var i = 0; i < num; i++) {
App.ShowAddress(i).then(function (ans) {
if(ans == account) {
alert(ans+' Hello');
alert(account+' Hi')
App.ShowFName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Name: ' + ans + ' </span><br/><br/>';
})
App.ShowLName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Surname: ' + ans + ' </span><br/><br/>';
})
App.ShowInstName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Institutions name: ' + ans + ' </span><br/><br/>';
})
App.ShowAddress(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Users address: ' + ans + ' </span><br/><br/>';
})
App.ShowCourseName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Course name: ' + ans + ' </span><br/><br/>';
wrapper.innerHTML += '<span class="test"></span><br/><br/>';
})
}
})
}
})
},
EDIT 1: This was the code i used before and it did the job, but now I wanted to add 1 thing and hit a wall.
loopforCetrs : function() {
var num;
var account = web3.currentProvider.selectedAddress;
App.contracts.StudentState.deployed().then(function (instance) {
return instance.showNumOfContracts();
}).then(function (numOfCert) {
num = numOfCert;
var wrapper = document.getElementById("myHTMLWrapper");
for (var i = 0; i < num; i++) {
App.ShowFName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Name: ' + ans + ' </span><br/><br/>';
})
App.ShowLName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Surname: ' + ans + ' </span><br/><br/>';
})
App.ShowInstName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Institutions name: ' + ans + ' </span><br/><br/>';
})
App.ShowAddress(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Users address: ' + ans + ' </span><br/><br/>';
})
App.ShowCourseName(i).then(function (ans) {
wrapper.innerHTML += '<span class="test">Course name: ' + ans + ' </span><br/><br/>';
wrapper.innerHTML += '<span class="test"></span><br/><br/>';
})
}
})
},
Upvotes: 1
Views: 58
Reputation: 11070
Use promises the way they were intended. That code is frankly nightmarish to look at when it could be so much simpler with ES6 async/await
and template literals:
loopforCetrs : async function() {
const account = web3.currentProvider.selectedAddress;
const numOfCert = await (await App.contracts.StudentState.deployed()).showNumOfContracts());
const wrapper = document.getElementById("myHTMLWrapper");
for (let i = 0; i < numOfCert; i++) {
if((await App.ShowAddress(i)) == account) {
//alert(ans+' Hello'); no more ans
alert(account+' Hi');
wrapper.innerHTML += `<span class="test">Name: ${await App.ShowFName(i)} </span><br/><br/>`;
wrapper.innerHTML += `<span class="test">Surname: ${await App.ShowLName(i)} </span><br/><br/>`;
wrapper.innerHTML += `<span class="test">Institutions name: ${await App.ShowInstName(i)} </span><br/><br/>`;
wrapper.innerHTML += `<span class="test">Users address: ${await App.ShowAddress(i)} </span><br/><br/>`;
wrapper.innerHTML += `<span class="test">Course name: ${await App.ShowCourseName(i)} </span><br/><br/>`;
wrapper.innerHTML += `<span class="test"></span><br/><br/>`;
}
}
}
This way, you won't run into issues with i
being the wrong value when the callbacks have resolved since everything is awaited and is guaranteed to fully resolve with in that loop iteration before i
has changed values.
There's still a lot of redundancy but my preferred way to fix that would be to add methods to App
that return more than a measly single piece of information. Have one that returns all relevant information instead and you reduce another 5 lines of redundant code and greatly improve performance and efficiency.
Upvotes: 3