Nodejs single callback after searching from 2 mongodb collections
As the previous answer, you can use async module to complete this task. There are many functions to control the non-blocking nature of node. Here I will recommend you to use "parallel" method. As the queries are independent of each other, it will be faster than "waterfall" method.
According to your question the code will look like this.
var async = require('async');async.parallel([ (cb) => { Stud.findOne( { _id: userid }, cb ); }, (cb) => { Prof.findOne( { _id: userid }, cb ); }],(err, result) => { if (err) { //handle error return; } //result will be an array where the first element will be the result of first query and // second element will be the query result for the second query // so according to this ..... if (result[0]) { //id is matched with Stud collection //result[0] is the student doc } else if (result[1]) { //id is matched with Prof collection //result[0] is the professor doc } else { //Neither Stud or Prof }}
);
You can read about the async methods from the asyn documentation
You can use waterfall method of async mudule to out from this issue
async.waterfall([ function(callback) { //your fist query method can go here callback(null, query_result1); }, function(first_result1, callback) { // your second query method go here callback(null, query_result2); }], function (err, result) { // final result'});
For the answer to your question, apply @abdulbarik post.
Here is other stuff about your actual code :
- Cut your request into functions
- When you are using callbacks, use them to return the error properly. Do not throw.
- You do not need to put
_id
key into quote
Remarks:
- Because of you are using node.js that now support ES6 (most of it), use it. Simplier to read and more efficient.
Sample about callbacks and function cut. I let you do the rest which is es6, waterfall handling.... You can look at Promise and Async/Await pattern tho.
// Check if there is a studentfunction check_student(user_id, callback) { Stud.findOne({ _id: user_id }, function (err, stud) { if (err) return callback(err, false); // stud here can worth false return callback(false, stud); });}
// Check if there is a proffunction check_prof(user_id, callback) { Prof.findOne({ _id: user_id }, function (err, prof) { if (err) return callback(err, false); // prof here can worth false return callback(false, prof); });}
// Get Stud not Prof infofunction check_user_info(user_id, callback) { // Look if user_id match a stud check_student(user_id, function (err, result) { // We have an error if (err) return callback(err, false); // We have a student if (result) return callback(false, result); // Check if user_id match a prof check_prof(user_id, function (err, result) { // We have an error if (err) return callback(err, false); // We have a prof if (result) return callback(false, result); // No result at all return callback(false, false); }); });}
How you call it
check_user_info(user_id, function (err, result) { // ...});
Example of code with promise :
// Check if there is a student function check_student(user_id) { return new Promise((resolve, reject) => { Stud.findOne({ _id: user_id }, (err, stud) => { if (err) return reject(err); // prof here can worth false return resolve(stud); }); }); } // Check if there is a prof function check_prof(user_id) { return new Promise((resolve, reject) => { Prof.findOne({ _id: user_id }, (err, prof) => { if (err) return reject(err); // prof here can worth false return resolve(prof); }); }); } // Get Stud not Prof info function check_user_info(user_id) { return Promise.all([ check_student(user_id), check_prof(user_id), ]); }
check_user_info(user_id) .then([ stud, prof, ] => { // Handle result }) .catch((err) => { // Handle error });