Sails.JS - 创建的用户不会返回用户对象

时间:2017-09-04 16:39:03

标签: node.js mongodb sails.js sails-mongo

我的Sails 1.0应用程序中有一个函数,它将一个新用户添加到MongoDB,然后最后应该将User对象作为JSON返回...

用户确实已添加到集合中,但在尝试获取新User对象的_id时会引发错误。当我尝试console.log()时,createdUser会以Undefined的形式返回。试图弄清楚用户如何在Mongo中创建但不能作为同一函数中的对象返回?

简而言之,Register()函数执行以下操作:

  • 验证一些输入
  • 检查有效的电子邮件地址
  • 加密密码
  • 查找Gravatar网址(如果适用)
  • 将用户插入集合
  • 在req.session中设置user._id(错误发生在此处)
  • 将用户对象作为JSON返回

错误:

info: ·• Auto-migrating...  (alter)
info:    Hold tight, this could take a moment.
info:  ✓ Auto-migration complete.

warn: Ignored attempt to bind route (/resend-username) to unknown action :: UserController.resendUsername
info:
info:                .-..-.
info:
info:    Sails              <|    .-..-.
info:    v1.0.0-37           |\
info:                       /|.\
info:                      / || \
info:                    ,'  |'  \
info:                 .-'.-==|/_--'
info:                 `--'-------'
info:    __---___--___---___--___---___--___
info:  ____---___--___---___--___---___--___-__
info:
info: Server lifted in `D:\Development\Sails\goknack-sails-1.0`
info: To shut down Sails, press <CTRL> + C at any time.

debug: -------------------------------------------------------
debug: :: Tue Sep 05 2017 18:08:33 GMT-0500 (Central Daylight Time)

debug: Environment : development
debug: Port        : 1337
debug: -------------------------------------------------------
undefined
D:\Development\Sails\goknack-sails-1.0\node_modules\mongodb\lib\utils.js:123
    process.nextTick(function() { throw err; });
                                  ^

TypeError: Cannot read property '_id' of undefined
    at D:\Development\Sails\goknack-sails-1.0\api\controllers\UserController.js:259:47
    at D:\Development\Sails\goknack-sails-1.0\node_modules\parley\lib\private\Deferred.js:232:16
    at _afterTalkingToAdapter (D:\Development\Sails\goknack-sails-1.0\node_modules\waterline\lib\waterline\methods\create.js:282:22)
    at D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\lib\private\do-with-connection.js:223:16
    at D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\lib\private\do-with-connection.js:123:18
    at Object.success (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\lib\private\build-std-adapter-method.js:61:47)
    at afterMaybeArtificiallyWaiting (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\node_modules\machine\lib\private\intercept-exit-callbacks.js:406:21)
    at maybeArtificiallyWait (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\node_modules\machine\lib\private\intercept-exit-callbacks.js:220:20)
    at afterPotentiallyCaching (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\node_modules\machine\lib\private\intercept-exit-callbacks.js:240:11)
    at _cacheIfAppropriate (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\node_modules\machine\lib\private\intercept-exit-callbacks.js:98:18)
    at Function._interceptExit [as success] (D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\node_modules\machine\lib\private\intercept-exit-callbacks.js:111:9)
    at D:\Development\Sails\goknack-sails-1.0\node_modules\sails-mongo\lib\private\machines\create-record.js:99:22
    at D:\Development\Sails\goknack-sails-1.0\node_modules\mongodb\lib\collection.js:437:18
    at handleCallback (D:\Development\Sails\goknack-sails-1.0\node_modules\mongodb\lib\utils.js:120:56)
    at D:\Development\Sails\goknack-sails-1.0\node_modules\mongodb\lib\collection.js:743:5
    at D:\Development\Sails\goknack-sails-1.0\node_modules\mongodb-core\lib\connection\pool.js:461:18
                              ^

我尝试将id切换为_id,因为它是Mongo但没有运气,当我尝试console.log createdUser时它是Undefined。

正在数据库中创建记录...我可能会对可能搞砸的任何帮助表示感谢。

enter image description here

我正在使用的完整注册功能:

  register: function (req, res) {

    if (_.isUndefined(req.param('first'))) {
      return res.badRequest('A first name is required!');
    }

    if (_.isUndefined(req.param('last'))) {
      return res.badRequest('A last name is required!');
    }

    if (_.isUndefined(req.param('phone'))) {
      return res.badRequest('A phone number is required!');
    }

    if (_.isUndefined(req.param('email'))) {
      return res.badRequest('An email address is required!');
    }

    if (req.param('email') !== req.param('emailConfirm')) {
      return res.badRequest('Email addresses do not match!');
    }

    if (_.isUndefined(req.param('password'))) {
      return res.badRequest('A password is required!');
    }

    if (req.param('password').length < 6) {
      return res.badRequest('Password must be at least 6 characters!');
    }

    if (req.param('password') !== req.param('confirmPassword')) {
      return res.badRequest('Passwords do not match!');
    }

    if (_.isUndefined(req.param('tos'))) {
      return res.badRequest('You must review and accept the Goknack Terms of Service & Privacy policy.');
    }



    Emailaddresses.validate({
      string: req.param('email'),
    }).exec({
      // An unexpected error occurred.
      error: function (err) {
        return res.serverError(err);
      },
      // The provided string is not an email address.
      invalid: function () {
        return res.badRequest('Doesn\'t look like an email address to me!');
      },
      // OK.
      success: function () {

        Passwords.encryptPassword({
          password: req.param('password'),
        }).exec({

          error: function (err) {
            return res.serverError(err);
          },

          success: function (result) {

            var options = {};

            // gravitar image for user, if present
            try {

              options.gravatarURL = Gravatar.getImageUrl({
                emailAddress: req.param('email')
              }).execSync();

            } catch (err) {
              return res.serverError(err);
            }

            options.email = req.param('email');
            options.username = req.param('username');
            options.encryptedPassword = result;
            options.deleted = false;
            options.deletedDate = '';
            options.admin = false;
            options.banned = false;
            options.paypalEmail = '';


            // validate that email address has not been used before
            User.find({email: req.param('email')}).exec(function(err, user) {
              if (err) {
                return res.negotiate(err);
              }

              if (user.length > 0) {
                return res.badRequest('Invalid email, this email address is already in use.');
              } else {
                // create new user
                User.create(options).exec(function (err, createdUser) {

                  if (err) {
                    console.log('the error is: ', err.invalidAttributes);
                    return res.negotiate(err);
                  }

                  // Log the user in
                  console.log(createdUser);
                  req.session.userId = createdUser._id;

                  // NOTHING IS BEING RETURNED IN createdUser

                  return res.json(createdUser);
                });

              }
            });

          }
        });
      }
    });
  },

7 个答案:

答案 0 :(得分:3)

从sails 1.0开始,您需要指定您希望从create调用返回该模型。要通过createfetch进行链接{/ 1}}。

let createdUser = await User.create({ name: "Some name" }).fetch();

此外,await现在比回调更受欢迎。

有关此内容的更多信息:https://next.sailsjs.com/documentation/reference/waterline-orm/models/create

答案 1 :(得分:2)

这看起来很奇怪。但我看到一个可能的罪魁祸首......当您使用User.find()检查电子邮件唯一性时,我不承认您使用查找。你这样称呼它:

User.find({email: req.param('email')}, function(err, user) {
    //...
});

但我认为find不接受第二次输入。你可能意思是exec

User.find({email: req.param('email')}).exec(function(err, user) {
    //...
});

我无法遵循导致您的特定错误的确切逻辑,但如果您以某种方式执行一个不应该在那里的函数参数,那么修复它就是一个可以开始的地方。

答案 2 :(得分:0)

我有同样的问题。然后我尝试使用findOrCreate返回新记录。我认为这是Sails 1.0的一个错误,因为我从来没有遇到过0.12这个问题。

答案 3 :(得分:0)

我的回答很晚,但这可能会对将来有所帮助。语法如下:

User.find({email: req.param('email')}, function(err, user) {
    //...
});

是Mike McNeil在 Sails.js in action 一书中使用的语法。它确实有效,至少在V0.12中。

关于错误,我想到导致这个问题的唯一原因,即创建记录但未返回的是你在UserController上创建了自己的create()方法,并且一旦创建就不返回该对象。

答案 4 :(得分:0)

我不知道是否有人想到了这一点,我今天在Hails版本的Sails v1.0上遇到了同样的问题。

我终于放弃并安装了v0.12,移植了我的控制器和模型,它工作正常。

这必须是v1.0中的一个错误,其中.exec(function(err,result){...})和.then(function(result){...})。catch(function(err)) {...})返回一个对象!

我可以证明await / fetch()方法在v1.0中有效,但我不确定如何使用文件上传来实现。所以v0.12它仍然存在。

答案 5 :(得分:0)

试试这个:

User.create({...}, function(err, createdUser) {
    //...
}, { fetch: true });

我希望这有帮助:)问题是在sails 1.0中,waterline不会自动获取创建/更新的对象,你需要添加{fetch:true}以获取创建的对象。

此方法也可以用于等待:

var createdUser = await User.create({...}).fetch();

但是如果你想使用传统的Node回调,那么上一个例子应该可以工作!

答案 6 :(得分:0)

我认为问题在于SailsJS v1中控制器的新体系结构。 建议使用动作。我有同样的错误。我用classic actions

修复了它

具体来说,我在文件“ api / controller / user / create.js”中使用了此代码:

module.exports = async function create (req, res) {
var userData = {
    /* pick from req.body... */
}
var user = await User.create(userData).fetch();
if(user){
  /* ... code to process the user object ... */
}

我希望这对其他人有帮助。 最好的问候!