mongodbmongoose

Does mongoose findOne on model return a promise?


I have a simple Node module that exports a function that makes a database query. The problem is that this function returns before the database query completes.

"use strict";

var mongoose = require('mongoose'),
    Model    = require('./entities/user/model'),
    _        = require('underscore');

let dao = new Model(mongoose);

module.exports.isAdmin = function(user_id) {
  var params = {'roles': 'admin'};

  dao.findOne(params, function(err, user) {
    if (err) {
      logger.error(err);
      return false;
    }
    if (_.indexOf(user.roles, 'admin') != -1) {
      logger.info("admin user: " + user._id);
      if (user._id == user_id) return true;
    }
    return false;
  });
};

isAdmin function searches the users collection in order to find out if user_id belongs to admin user.

The problem is that isAdmin function doesn't wait for the response of findOne query.

How could I force the isAdmin function to return only when query returns results ?


Solution

  • Because findOne is async function, one way to return from it is through callback function

    module.exports.isAdmin = function(user_id, callback) {
      var params = {'roles': 'admin'};
    
      dao.findOne(params, function(err, user) {
        if (err) {
          logger.error(err);
          callback && callback(false);
        }
        if (_.indexOf(user.roles, 'admin') != -1) {
          logger.info("admin user: " + user._id);
          if (user._id == user_id)
              callback && callback(true);
        }
        callback && callback(true);
      });
    };
    
    isAdmin(userId, function(v) {
        console.log(v);
    })
    

    Another way is to get Promise in findOne, as this doc said, .exec() gives you a fully-fledged promise. Even with Promise, to meet you requirement, the result could be returned through callback function.

    module.exports.isAdmin = function(user_id, callback) {
      var params = {'roles': 'admin'};
    
      var queryPromise = dao.findOne(params).exec();
      queryPromise.then(function(user) {
          if (_.indexOf(user.roles, 'admin') != -1) {
            logger.info("admin user: " + user._id);
            if (user._id == user_id)
              callback && callback(true);
          }
        }, function(err) {
          callback && callback(false);
      });
    };