NodeJS和MongooseJS:从验证器中的回调访问值

时间:2013-09-29 23:54:40

标签: javascript node.js mongodb mongoose

我正在尝试在NodeJS / ExpressJS / MongoDB / Mongoose应用程序中使用验证器和express-validator来确认用户没有使用已经注册的电子邮件地址。我已经在电子邮件字段中有一个唯一索引,但我要做的是使用一种方法将所有验证保存在一个位置。因此,我的问题是:使用express-validator验证唯一性。

我已经创建了架构方法来查找电子邮件地址,并且它正在运行。我已经创建了自定义验证器,并将其连接到控制器中。它也有效。我的问题是我不知道如何通过回调与控制器中的验证器通信架构方法的结果。

user.js(模型)

...

/**
 * Check for email addresses already in the collection
 */
 checkEmailDupes: function(req, cb) {
   this.model('User').findOne({email: req}, function (err, user) {
     if (err) {
       return cb(err);
     }
     cb(null, user); // this is passing back the expected result
   });
},

...

users.js(控制器)

...
// The call to the custom validator (shown below)
req.assert('email', 'Email must be unique').checkEmailDupes(user);
...

// Check for email addresses that are already registered
expressValidator.Validator.prototype.checkEmailDupes = function(user) {
  user.checkEmailDupes(this.str, function (err, result) {
    if (err) {
      console.log('An error occurred in checkEmailDupes');
    }
    else {
      console.log('Found a user in checkEmailDupes');
      console.log(result); // this is producing the expected result
    }
  });
  return this.error(this.msg || 'Looks like this email address has already been registered');
  return this;
}

我知道return this.error(this.msg...)需要去其他地方。理想情况下,我会把它扔进回调中,但当我这样做时,我得到了

  

TypeError:对象#没有方法'错误'

2 个答案:

答案 0 :(得分:0)

试试这个(创建一个部分error函数,其范围和第一个参数已经'填充'了):

expressValidator.Validator.prototype.checkEmailDupes = function(user) {
  var error = this.error.bind(this, this.msg || 'Looks like this email address has already been registered');

  user.checkEmailDupes(this.str, function (err, result) {
    if (err) {
      console.log('An error occurred in checkEmailDupes');
      return error();
    }
    else {
      console.log('Found a user in checkEmailDupes');
      console.log(result); // this is producing the expected result
    }
  });
  return this;
}

但是,这里可能存在一些问题,因为user.checkEmailDupes是异步的,但expressValidator.Validator.prototype.checkEmailDupes不是。我不知道验证器模块的内部工作原理,知道这是否是一个问题。

编辑:也许this answer我给了一段时间也许有用。使用express-validator验证数据库约束可能不是最佳解决方案。

答案 1 :(得分:0)

我最终无法使用此方法。感谢@robertklep和他的反馈,我决定使用mongo传回的错误代码(在为电子邮件找到非唯一值的情况下,它是MongoError: E11000 duplicate key error index)并根据该错误设置错误消息

它最终看起来如下(在用户控制器中):

user.save(function(err) {
  if (err) {
    // Instantiate the errors array
    var errors = [];

    // Email address already in DB
    if (err.code == 11000) {
      // Build the error object
      var error = {
        param: 'email',
        msg: 'The email address entered has already been registered',
        value: ''
      };

      // Push the error onto the errors array
      errors.push(error);
    }

    return res.render('users/signup', {
      errors: errors,
      user: user
    });
  }

  ...