0

Trouble finding the reason why JavaScript for loop is not executing. Wrote 2 simple functions below that I want to execute and run i.e.: Bought method should try to "simulate" synchronous code. The problem is that for some reason the for loop in the addNodes() method is never executed. However, if I run this separately i.e. for example line by line

var result = [];
var addressBookNodes = await generateAddressBooksNodes();
addNodes(result, addressBookNodes);

that tells me that the code is running fine however most likely it has something to do with the asynchronous nature of the generateAddressBooksNodes method. If I simply run the command :

var addressBookNodes = await generateAddressBooksNodes();

in the browser, I get an array of objects exactly what I was expecting to get. Basically the generateAddressBooksNodes returns a promise and when that promise is resolved I can see the correct array returned however what I do not understand why the for loop is not executed if the nodes objects have at least one element as shown in the picture below.

function addNodes(result, nodes){
    console.log("3");
    console.log(nodes);
    for (var num in nodes) {
        console.log("4");   
        let singleNode = nodes[num];
        console.log(singleNode);        
        console.log("5");
        result.push(singleNode);
    }
}

async function getAddressBookAndContactNodes() {  
    var result = [];
    console.log("1");
    var addressBookNodesPromise = generateAddressBooksNodes();
    addressBookNodesPromise.then( (arrayOfAddressBookNodes) => {
        console.log("2");
        addNodes(result, arrayOfAddressBookNodes);          
    })      
    return result;  
}

here is the picture of what that looks in the browser

Update 26 August 2020 :

After poking around the "arrayOfAddressBookNodes" object i noticed something really strange. I added additional print statement and printed the length of the "arrayOfAddressBookNodes" array. The length of the array is 0 when runned in the function. I do not understand how the length can be 0 if the object is printed shortly before the for loop and as shown on the picture below the length there is :1. What the hell is going on here?

I found another article i.e. JavaScript Array.length returning 0 that is basically explaining this. And in one of the commends it has been mentioned to use Map instead of an Array. I decided to use Set, and still get the same error i.e. the size of the set is 0 although the Set contains an object. i.e. below is the code and the picture of that execution.

  async function getAddressBookAndContactNodes() {
    var result = new Set();
    console.log("1");
    var addressBookNodes = await generateAddressBooksNodes();
    console.log("2");
    console.log(addressBookNodes);
    console.log("3");
    console.log("addressBookNodes size : " + addressBookNodes.size);
    addressBookNodes.forEach(function(value) {
        result.add(value);
    });
    console.log("6");
    console.log(result);
    console.log("7");
    return result;
}

example using set

all this is really confusing to someone having a c++ backgroud, it makes my head explode.

Update 2 : 26 August 2020. Ok i solved my problem. The problem was that the the promises are not working withing the for loop everything is explained here.

i need to use the regular "for (index = 0; index < contactsArray.length; ++index) " instead of foreach. after that it all worked. Somehow this leaves the impression that the tools of the language are broken in so many ways.

12
  • 3
    You are returning the result before the promise then() populates the array Commented Aug 25, 2020 at 16:11
  • @charlietfl can you give me a hint what would be a common solution to that i.e. i have learned that i can not return from the promise, and thus i am not sure what to do here Commented Aug 25, 2020 at 16:13
  • To be honest I don't really see why you need to push all those into a different array and don't just return addressBookNodesPromise and use the array it resolves with Commented Aug 25, 2020 at 16:16
  • well i have multiple arrays i.e. one for address books , one for contacts , mailing lists and i need to combine all the objects from those array into a single one in this case it is called "result". I have just tried to show a simplified version of the code which is not working. Commented Aug 25, 2020 at 16:20
  • 1
    OK, makes sense... BTW a simpler way to add them without needing a loop is result.push(...nodes) Also should not use for in on arrays Commented Aug 25, 2020 at 16:25

1 Answer 1

1

If generateAddressBooksNodes is returning a promise, you can use async to wait for the results:

async function getAddressBookAndContactNodes() {

    var result = [];
    console.log("1");
    var addressBookNodesPromise = await generateAddressBooksNodes();
    // note await here. Also, unless you're using this at a later time in your code, you can save space by not assigning it to a variable and simply returning generateAddressBooksNodes
    
    addNodes(result, arrayOfAddressBookNodes);
    return result;
}
Sign up to request clarification or add additional context in comments.

2 Comments

I do not understand why this should solve the problem, although i must say await seems much cleaner and i will definitely use it. the parts 4 and 5 do not run. Are you sure that is the problem
just tried this , this is not solving the original problem where the for loop is not beeing runned

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.