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);
});
Hatchet
5,4161 gold badge35 silver badges43 bronze badges
asked Jul 10, 2018 at 23:32

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.

answered Jul 10, 2018 at 23:49
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.

answered Jul 10, 2018 at 23:42

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.