Search code examples
node.jspromisereturnundefinedes6-promise

NodeJS - Getting 'undefined' while returning values from Promise.all function


I have the following code:

var Promise = require('bluebird');
var reqP = Promise.promisifyAll(require('request-promise'));

var requestsArray = [];

function getRequests(){

    const req1 = {
        method: 'GET',
        uri: 'url'
    }
    const req2 = {
        method: 'GET',
        uri: 'url'
    }
    const req3 = {
        method: 'GET',
        uri: 'url'
    }
    const req4 = {
        method: 'GET',
        uri: 'url'
    }
    const req5 = {
        method: 'GET',
        uri: 'url'
    }
    const req6 = {
        method: 'GET',
        uri: 'url'
    }
    const req7 = {
        method: 'GET',
        uri: 'url'
    }

    Promise.all([reqP(req1), reqP(req2), reqP(req3),
                reqP(req4), reqP(req5), reqP(req6),
                reqP(req7)])
        .then(function (results) {
            for(re in results){
                switch(re){
                    case '0':
                        requestsArray.push({'req1':{'value':JSON.parse(results[re])}})
                    break;
                    case '1':
                        requestsArray.push({'req2':{'value':JSON.parse(results[re])}})
                    break;
                    case '2':
                        requestsArray.push({'req3':{'value':JSON.parse(results[re])}})
                    break;
                    case '3':
                        requestsArray.push({'req4':{'value':JSON.parse(results[re])}})
                    break;
                    case '4':
                        requestsArray.push({'req5':{'value':JSON.parse(results[re])}})
                    break;
                    case '5':
                        requestsArray.push({'req6':{'value':JSON.parse(results[re])}})
                    break;
                    case '6':
                        requestsArray.push({'req7':{'value':JSON.parse(results[re])}})
                    break;
                }
            }
            return requestsArray;
        })

        .catch(function (err) {
            console.log('Error: ', err);
        })

}

module.exports = {getExampleFile};

The return requests Array is being returned empty (or undefined) because if runs without waiting for the for loop to finish.
How can I make it wait for the for loop to finish, as in this case it's already nested in a .then()?

I have been going through a lot of options, starting with Promises, using another function that will be called upon the 6th iteration and going over async await.
Been playing around with it, but still not entirely sure how to implement each and every one of the suggested solutions in that case though.

Thank you.


Solution

  • My comment above stands: return Promise.all(.....

    A prettier way to produce the structure you're going for is to create a promise for each async call that takes the request params as input and writes the result of the request back to the same object (think of it as a to-do list), like this:

    function getRequests(){
        const req1 = {
            method: 'GET',
            uri: 'url'
        }
        const req2 = {
            method: 'GET',
            uri: 'url'
        }
        // etc.
        let todoList = [{ request:req1 }, { request:req2 }, ...];
        let promises = todoList.map(item => {
            return reqP(item.request).then(result => {
                item.value = JSON.parse(result);
                return item;
            });
        });
        return Promise.all(promises);
    }
    

    The idea is to return promises that when fulfilled will have associated the request result with the request. getRequests() will return promise that resolves to:

    [{ request:req1, value:/* json parsed result */}, {...}, ...},