2

I want to take data with two collections. How to send this data in one response?

This is my code:

    //RETURN SINGLE QUERYE
exports.findById = function(req, res) {
    //Get Params
    var querye_id =new BSON.ObjectID(req.params.id); 
    var querye;

    //Get Single Querye
    db.collection('queryes', function(err, collection) {
        collection.findOne({'_id':querye_id}, function(err, item) {
            querye=item;
        });

    });
    //Get Questions and Answers
    db.collection('questions', function(err, collection) {
        collection.find().toArray(function(err, items) {
            querye.questions=items;
        });
    });

    //Send Response
     res.send(querye);

};

I have varible querye as undefined. How to solve this?

2 Answers 2

4
var async = require('async');

function getQueries(id, callback) {
  db.collection('queryes', function(err, collection) {
    collection.findOne({'_id':id}, callback);
  });
}

function getQuestions(callback) {
  db.collection('questions', function(err, collection) {
    collection.find().toArray(callback);
  });
}

exports.findById = function(req, res) {
  var querye_id =new BSON.ObjectID(req.params.id);
  async.parallel({
    querye: async.apply(getQueries, query_id),
    questions: getQuestions
  }, function (error, results) {
    if (error) {
      res.status(500).send(error);
      return;
    }
    results.querye.questions = results.questions;
    res.send(results.querye);
  });
};
-1

What you should probably do is use deferreds/promises to get the results in a waterfall manner then return the results when everything is completed.

I like to use the async library for node.

https://npmjs.org/package/async

What this lets you do is queue up all of your async functions then report back success/failure. At the very end you will get the results.

Assuming you already required the async module your code would look something like this.

exports.findById = function(req, res) {
    //Get Params
    var querye_id =new BSON.ObjectID(req.params.id);

    async.waterfall([
        function(callback){
            //Get Single Querye
            db.collection('queryes', function(err, collection) {
                collection.findOne({'_id':querye_id}, function(err, item) {
                    callback(null, item);
                });
            });
        },
        function(arg, callback){
            //Get Questions and Answers
            db.collection('questions', function(err, collection) {
                collection.find().toArray(function(err, items) {
                    arg.questions=items;
                    callback(null, arg);
                });
            });    
        }],function(err, results){
            //Send Response
            res.send(results);
    });
};
2
  • Yeah, you are right. That was a simple oversight. The same library also offers a "waterfall" method that will cascade calls. That could be used instead with very little code change. Commented Oct 26, 2013 at 16:24
  • I updated my answer to show the change from parallel to waterfall. Commented Oct 26, 2013 at 16:28

Not the answer you're looking for? Browse other questions tagged or ask your own question.