klp klp - 2 months ago 6
Node.js Question

How to perform forloop in node js

Acoording to the data available ui should get 2 reults but getting only one since i put res.send in the looop so it is getting ended ,can anyone help me out please.......

exports.getrequestsdetails = function(req, res) {
var params = req.params;
console.log(params)
var record = db.collection('requests');
var item = {
"sent_id": params.id,
"status": 1
}
record.find(item).toArray((err, result) => {
if (err) {
return
}
if (result) {
for (var i in result) {
var id = result[i].recieved_id;
var profile = db.collection('profile');
profile.find({
'_id': new ObjectId(id)
}).toArray((err, resp) => {
if (err) {
return
}
if (resp) {
console.log(resp);
}
else{
}
});
}
res.send(resp);
}//end of if loop
else {
response = {
status: 'fail',
data: []
};
}

});

}

Answer

The problem is in getting the profiles. You are using mongodb's find which is asynchronous. Therefore in your for cycle you start fetching the profiles, but then you send out the res.send well before the fetching of the profiles is finished.

The call back from profile.find(... will be executed after the res.send. Apart from this, the resp variable is inside the find callback and you are trying to res.send it outside.

To deal with this, either you use async or promises. See the below code that uses promises.

var Promise = require('bluebird')

exports.getrequestsdetails = function(req, res) {
    var params = req.params;
    console.log(params)
    var record = db.collection('requests');
    var item = {
        "sent_id": params.id,
        "status": 1
    }

    record.find(item).toArray((err, result) => {
        if (err) {
            return
        }
        if (result) {

            var profiles_to_get = []
            var profiles = []

            for (var i in result) {
                var id = result[i].recieved_id;
                profiles_to_get.push(get_profile(id, profiles))
            }

            Promise.all(profiles_to_get)
                .then(() => {
                    res.send(profiles);
                })
        } //end of if loop
        else {
            response = {
                status: 'fail',
                data: []
            };
        }

    });

    function get_profile (id, profiles) {
        return new Promise(function (resolve, reject) {
            var profile = db.collection('profile');
                profile.find({
                    '_id': new ObjectId(id)
                }).toArray((err, resp) => {
                    if (err) {
                        reject(err)
                        return
                    }
                    if (resp) {
                        profiles.push(resp)
                        resolve()
                    } else {
                        reject()
                    }
                });
        })
    }

}

How this works is that it creates a list of profiles to find and stores it in the var profiles_to_get = []. The you use Promise.All(profiles_to_get) which will let you do stuff after all the profiles have been fetched.