1

I am new to Node JS and I'm struggling to understand how to run a for loop inside an asynchronous function. There is another async function inside the for loop.

I should be getting a response of some values in promArray. However, I am getting an empty array.

const rp = require('request-promise');

const options2 = {
    uri: 'uri',
    method: 'GET',
    auth: {
        'user': 'username',
        'pass': 'password'
    }
};
var promArray = [];


function executeMethod() {

    rp(options2).then(function(body) {

        const jsonData = JSON.parse(body).result;
        // iterate through the pods

        jsonData.forEach(element => {
            promArray.push(getProjectName(element.u_hig_proj_name.value))
        });


    });

    return Promise.all(promArray);
}

function getProjectName(projectSysId) {
    const projectTableAttrbutes = {
        uri: 'uri',
        method: 'GET',
        auth: {
            'user': 'username',
            'pass': 'password'
        }
    };
    return new Promise(function(res, rej) {
        // call the project table
        rp(projectTableAttrbutes).then(function(body) {
            //console.log(JSON.parse(body).result.name);
            res(JSON.parse(body).result.name);
        })
    })
}


// final execution 

executeMethod().then(function(done) {

    console.log(done);

});

2 Answers 2

1

The problem here is that your forEach is within the then block. That means that it will be executed asynchronously.

Your return statement however is located outside of the then, so it will be executed immediately, before the promise has resolved and the then block has run. Thats why it's empty.

This would be a possible solution:

function executeMethod() {
    return rp(options2).then(function(body) {

        const jsonData = JSON.parse(body).result;
        // iterate through the pods

        jsonData.forEach(element => {
            promArray.push(getProjectName(element.u_hig_proj_name.value))
        });

        return Promise.all(promArray);

    });
}

In this solution, the two promises are chained and executed consecutively. First, the outer promise is returned (return rp(...)). Within it's then block, the second promise is returned (return Promise.all(...)). That will be the final value, that executeMethod will resolve with.

I highly recommend checking out this article to learn more about promise chaining, since it is a crucial tool when working with promises.

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

Comments

0

When you first call executeMethod(), your promArray is empty, so all of the promises in the array (that is, all zero of them) are resolved, so the promise resolves right away. I'm guessing the promises you're actually interested in are those generated in the jsonData.forEach call, since you're adding those to promArray. Therefore, I'd recommend actually saying jsonData.map and then returning each of those getProjectName calls as promises, then wrap the whole .map call in Promise.all:

return Promise.all(
    jsonData.map(
        element => getProjectName(element.u_hig_proj_name.value)
    )
);

And then you can use that like another promise.


Also, I don't quite understand what you're doing in the getProjectName function - why are you creating a new Promise wrapper around the request? It's already a promise.

Comments

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.