【问题标题】:Nodejs Mongoose Saving model undefined is not a functionNodejs Mongoose保存模型未定义不是函数
【发布时间】:2015-09-29 05:40:42
【问题描述】:

我使用 Nodejs Express 路由和 Mongoose 来持久化数据。 我没有问题地完成了核心路由 CRUD 操作。但是,当我尝试对模型的一个字段执行一些操作,然后尝试使用 model.save 保存模型时,它会说 .save() 方法:“未定义不是函数”

所以,这里是代码。 sn-p 数字 (1) 工作得很好:

router.put('/:myId', function (req, res, next) {
var ourUpdateData = req.body;
Model.findOne({myId: req.params.myId.toString()}, function (err, foundModel) {
    if (err) throw err;

    if (ourUpdateData.fieldA) foundModel.fieldA = ourUpdateData.fieldA;
    if (ourUpdateData.fieldB) foundModel.fieldB = ourUpdateData.fieldB;
    if (ourUpdateData.fieldC) foundModel.fieldC = ourUpdateData.fieldC;
    if (ourUpdateData.fieldD) foundModel.fieldD = ourUpdateData.fieldD;
    if (typeof ourUpdateData.fieldArray === "object") ourUpdateData.fieldArray = ourUpdateData.fieldArray;

    foundModel.save(function (err, updatedModel) {
        if (err) throw err;
        res.send(updatedmodel);
    });
});

});

所以模型有 6 个字段:fieldA、..B、..C、..D、myId 标识为索引,一个字段是一些值 fieldArray 的数组。上面的示例保存了模型,工作正常。 但是,如果我现在尝试对数组字段 fieldArray 执行某些操作,然后保存模型,它会在我使用 model.save() 时抛出“未定义不是函数”。 所以sn-p(2)就是产生这个错误的代码:

    router.get('/:myId/:addThisToFieldArray', function(req, res, next) {
    var myId = req.params.myId;
    var addThisToFieldArray = req.params.addThisToFieldArray;
    Model.find({myId: myId}, function (err, model) {
        if (err) throw err;
        var fieldArray = model.fieldArray;
        fieldArray.push("New thing to FieldArray");
        var newFieldArray = fieldArray;
        if (typeof newFieldArray === "object") model.fieldArray = newFieldArray;
        model.save(function (err, updatedModel){
            if (err) throw err;
            res.send(updatedModel);
        });
    });
});

所以上面的东西在使用 model.save(..) 时会抛出“undefined is not a function”

我还尝试了 sn-p (2) 的第二个变体,我们称之为 sn-p (3),合并 .exec() 也不起作用,抛出相同的“未定义不是函数”模型.保存(..) 所以sn-p(3)是这样的:

    router.get('/:myId/:addThisToFieldArray', function(req, res, next) {
    var myId = req.params.myId;
    var addThisToFieldArray = req.params.addThisToFieldArray;
    Model.find({myId: myId}).exec(function (err, model) {
        if (err) throw err;
        var fieldArray = model.fieldArray;
        fieldArray.push("New thing to FieldArray");
        var newFieldArray = fieldArray;
        if (typeof newFieldArray === "object") model.fieldArray = newFieldArray;
        model.save(function (err, updatedModel){
            if (err) throw err;
            res.send(updatedModel);
        });
    });
});

如有任何意见和建议,我将不胜感激!

回应威尔森的尝试:

是的,我知道当我调用 model.find(.. 它会给出数组,如果我调用 model.findOne(.. 它会给出一个对象 json

我试图简化我的示例,在我的版本中我实际上确实使用了: "model[0].fieldArray = newFieldArray" 从 Array 拳头(数组本身)获取东西,然后分配给新值。

问题仍然存在,它给了我 model.save(.. "undefined is not a function" )

目前的代码是:

    router.get('/:myId/:addThisToFieldArray', function(req, res, next) {
    var myId = req.params.myId;
    var addThisToFieldArray = req.params.addThisToFieldArray;
    Model.find({myId: myId}).exec(function (err, model) {
        if (err) throw err;
        var fieldArray = model[0].fieldArray;
        fieldArray.push("New thing to FieldArray");
        var newFieldArray = fieldArray;
        if (typeof newFieldArray === "object") model[0].fieldArray = newFieldArray;
        model.save(function (err, updatedModel){
            if (err) throw err;
            res.send(updatedModel);
        });
    });
});

上面这个sn-p(4)给出了model.save(.."undefined is not a function"

【问题讨论】:

  • 使用findOne 而不是find
  • 好的,我会尝试这样做并评论我得到的内容

标签: javascript node.js mongoose save undefined


【解决方案1】:

当您在 Mongoose 中使用 find 方法时,它将返回一个数组,因为它可以发现一个或多个文档,因此在您的示例中,您通过其 id 查询一个特定元素,您应该抓住第一个元素返回的数组:

Model.find({myId: myId}).exec(function (err, 文档) { var model = 文档[0]; if (err) 抛出错误; var fieldArray = model[0].fieldArray;

这是一个例子:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost:27017/java-jedi');

var HackerSchema = new Schema({
  name: String,
  languages: [String]
});

var Hacker = mongoose.model('Hacker', HackerSchema);


// instantiating the model.
var oneHacker = new Hacker();
oneHacker.name = 'Richard Stallman';

oneHacker.save(function(err) {
  if (err) throw err;

  // finding the document intentionally for this example
  Hacker.find({_id: oneHacker._id}, function(err, hackers) {
    var hacker = hackers[0];

    // modifying the document and updating it.
    hacker.languages.push('Lisp');
    hacker.save(function(err) {
      if (err) throw err;

      console.log(hacker);
    });
  });

});

【讨论】:

  • 是的,我知道,如果我调用 model.find(..) 它返回一个数组,如果我调用 model.findOne(..) 它返回 json 对象,只有一件事.
【解决方案2】:

好吧,伙计们! 我要感谢威尔逊·巴尔德拉马,因为他基本上指出了正确的方向。

代码有效!但让我澄清一下。

  Hacker.find({_id: oneHacker._id}, function(err, hackers) {
var hacker = hackers[0];

// modifying the document and updating it.
hacker.languages.push('Lisp');
hacker.save(function(err) {
  if (err) throw err;

  console.log(hacker);
});

});

所以基本上因为 Model.find(.. 返回一个数组
当我们保存时,我们必须在保存之前从数组中获取东西。

因此,我的示例的更正和最终工作版本将是:

    router.get('/:myId/:addThisToFieldArray', function(req, res, next) {
    var myId = req.params.myId;
    var addThisToFieldArray = req.params.addThisToFieldArray;
    Model.find({myId: myId}).exec(function (err, model) {
        if (err) throw err;
        var fieldArray = model[0].fieldArray;
        fieldArray.push("New thing to FieldArray");
        var newFieldArray = fieldArray;
        if (typeof newFieldArray === "object") model[0].fieldArray = newFieldArray;
        model[0].save(function (err, updatedModel){
            if (err) throw err;
            res.send(updatedModel);
        });
    });
});

或者我们可以只使用 Model.findOne(.. 来避免混淆这个数组返回

这种情况下我们直接抓取:

router.get('/:myId/:addThisToFieldArray', function(req, res, next) {
var myId = req.params.myId;
var addThisToFieldArray = req.params.addThisToFieldArray;
Model.findOne({myId: myId}).exec(function (err, model) {
    if (err) throw err;
    var fieldArray = model.fieldArray;
    fieldArray.push("New thing to FieldArray");
    var newFieldArray = fieldArray;
    if (typeof newFieldArray === "object") model.fieldArray = newFieldArray;
    model.save(function (err, updatedModel){
        if (err) throw err;
        res.send(updatedModel);
    });
});
});

所以在第二种情况下 model[0].save(... 变成 model.save(... 直接抓取和保存。

再次感谢威尔逊·巴尔德拉马!!

【讨论】:

  • 很高兴它帮助了你,没问题!
猜你喜欢
  • 1970-01-01
  • 2015-11-13
  • 1970-01-01
  • 2012-09-07
  • 2019-03-18
  • 2016-02-03
  • 2020-10-22
  • 2019-02-20
  • 1970-01-01
相关资源
最近更新 更多