Search code examples
node.jspromisees6-promisenode-request

How to resolve multiple GET requests in a forEach using NodeJS


I have a number of stock tickers in a JSON file that I want to use to send multiple GET requests to get the price of that stock. The problem I'm having is how to send them off in parallel and how to resolve them.

Here is the code I have tried:

const stocks = require('./stocks.json')
var request = require("request");

    var stockTickers = stocks.map(x => x.stockopediaTicker)
    stockTickers.forEach(ticker => {
        var promises = []
        var options = {
            method: 'GET',
            url: 'https://www.stockopedia.com/ajax/get_prices/' + ticker + '/'
        };
        let todaysQuote = new Promise(function (res, rej) {
            request(options, function (error, response, body) {
                rej(error)
                res(body)
            });
        })
        promises.push(todaysQuote)
    });

    Promise.all(promises)
        .then((results) => {
            console.log(results)
        }).catch(err => console.log(err))

Solution

  • You were on the right path with your code.

    1. You just need to only call rej(err) if there is actually an error
    2. You shouldn't be attempting to share the same options object with all your requests (that might or might not cause problems)
    3. You need to declare promises in a higher scope where it can be used with Promise.all(promises):

    Here's what it would look like after fixing up those issues:

    const stocks = require('./stocks.json')
    const request = require("request");
    
    let promises = [];
    let stockTickers = stocks.map(x => x.stockopediaTicker);
    
    stockTickers.forEach(ticker => {
        let todaysQuote = new Promise(function (res, rej) {
            let options = {
                method: 'GET',
                url: 'https://www.stockopedia.com/ajax/get_prices/' + ticker + '/'
            };
            request(options, function (error, response, body) {
                if (error) {
                    rej(error);
                } else {
                    res(body);
                }
            });
        })
        promises.push(todaysQuote)
    });
    
    Promise.all(promises)
        .then((results) => {
            console.log(results);
        }).catch(err => console.log(err))
    

    The request-promise module is simpler to use as it already includes a promise wrapper and it's probably easier to use .map() to accumulate your array of promises.

    const stocks = require('./stocks.json')
    const rp = require("request-promise");
    
    Promise.all(stocks.map(x => {
        let options = {
            method: 'GET',
            url: 'https://www.stockopedia.com/ajax/get_prices/' + x.stockopediaTicker + '/'
        };
        return rp(options);
    })).then(results => {
        console.log(results);
    }).catch(err => {
        console.log(err);
    });