1

I am trying to implement async and request into an asynchronous API request action within one of my routers. The end point is just a query string and I'm trying to return an an array or object with the result of all of the calls. So far there are just two:

router.get('/', function(req, res) {
    async.parallel([
        function(next) {
            request(queryString + 'end point string', function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    var unsPAM = JSON.parse(body);
                };
                console.log(error);
            });
        },
        function(next) {
            request(queryString + 'end point string', function(error, response, body) {
                if (!error && response.statusCode == 200) {
                    var unsAll = JSON.parse(body);
                };
                console.log(error);
            });
        }], 
        function(err, results) {
            res.render("api-results", [results]);
        });
    });

This is the just of what I'm trying to do. If I console.log the result of each variable after the request it works properly, but nothing is being returned and my ejs template is not being served.

I have also tried using something like the below in various formats (array/object form) but I cannot seem to get it working:

res.render("api-results", { unsPAM: unsPAM, unsAll: unsAll });

I think its because the result of the request's aren't making it to the async array somehow. Any advice/best practice solutions/change of ideas would be greatly appreciated.

Thank you.

1 Answer 1

3

In each of the functions, you need to invoke the next() callback with null and the value you want to pass on, or an error object if unsuccessful. Without that, async.parallel() has no indication that the API calls ever completed.

To reduce the amount of repeated code, you can create a closure with the URL for each API endpoint:

function apiCall(url) {
    return function(callback) {
        request(url, function(error, response, body) {
            if (error || response.statusCode != 200) {
                return callback(error);
            }

            try {
                return callback(null, JSON.parse(body));
            } catch (error) {
                return callback(error);
            }
        });
    };
}       

router.get('/', function(req, res) {
    async.parallel([
        apiCall(queryString + 'end point string'),
        apiCall(queryString + 'end point string')
    ], function(err, results) {
        if (err) console.log(err);
        res.render("api-results", results);
    });
});

That will call res.render() with results as [unsPAM, unsAll]. If you would rather results be an object with the keys unsPAM and unsAll, call async.parallel() with an object instead of an array as the first parameter:

router.get('/', function(req, res) {
    async.parallel({
        unsPAM: apiCall(queryString + 'end point string'),
        unsAll: apiCall(queryString + 'end point string')
    }, function(err, results) {
        if (err) console.log(err);
        res.render("api-results", results);
    });
});
Sign up to request clarification or add additional context in comments.

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.