1

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/>';
                })
            }

      })
    },
6
  • yikes with that code. I see major issue with infamous for loop when i is not what you think it is Commented Dec 11, 2019 at 22:59
  • stackoverflow.com/questions/750486/… Commented Dec 11, 2019 at 23:01
  • yeah when the loop ends i is then the maximum value, I think the solution would be to avoid loops all together, but I just can't figure out how to do that Commented Dec 11, 2019 at 23:02
  • The link above shows you how to fix that problem. My question as a developer is WHY is there so many asynchronous calls? It is code smell which is not good. Commented Dec 11, 2019 at 23:04
  • The structure is all wrong. Why are there individual async calls just to get their first and last name? This is like, fetching the first name from mongodb, then making another query to fetch the last name. Commented Dec 11, 2019 at 23:07

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Oh that really looks and feels a lot better, I will try to do more research into the await function, but the numOfCert line is still problematic.
@RokasPo Yeah, my bad, misplaced a parenthesis. I've edited it, should work now.
Thank you a lot, I also might want to add that I don't intend to break after the first finding, but you've been a huge help!
@RokasPo Glad to be of help, as to the break statement I must have misinterpreted your question title. Edited it out so it's only the relevant stuff left.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.