Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for a loop to finish running before sending back a response in NodeJs?

I'm trying to send back an array of objects after a GET request to a URL but I can't figure out how to structure the logic so the return array fully populates before sending it to the client.

Below is my server side code for responding to the request. I used passport.js previously in the code to create a login portal and user object. I'm trying to take the "connections" array from the user who is making the request and sending them back an array of objects with the connection's name and picture. I know that the code below is incorrect syntax wise but it's an overview of what I'm trying to accomplish. I've tried doing it the callback way but that just kept leading me in circles because I couldn't figure out the correct logic for it.

router.get('/data', function(req, res, next) {
    var IdArr = req.user.connections;

    var retArr = [];

    function getUsers() {
        for (i = 0; i < IdArr.length; i++) {
            User.getUserById(IdArr[i], function(err, patient) {
                retArr[i] = {name:patient.name, pic:patient.profileImage};
            });
        }
    }

    function getDataAndSend() {
        function(getUsers(), function sendRes() { // I know this is incorrect syntax
            console.log(retArr);
            res.json(retArr);
        });
    }

    getDataAndSend();
});
like image 897
Ryan O'Shea Avatar asked Mar 04 '23 21:03

Ryan O'Shea


1 Answers

First of all, you should declare i, and when you do it should be with block-scope (let), so that the nested callback function will use the same variable.

You could check how many entries in retArr have been retrieved and call res.json once you know you have them all.

router.get('/data', function(req, res, next) {
    var IdArr = req.user.connections;
    var retArr = [];
    for (let i = 0; i < IdArr.length; i++) {
        User.getUserById(IdArr[i], function(err, patient) {
            retArr[i] = {name:patient.name, pic:patient.profileImage};
            if (Object.keys(retArr).length === IdArr.length) res.json(retArr);
        });
    }
});
like image 66
trincot Avatar answered May 03 '23 22:05

trincot