简体   繁体   English

Nodejs Mongoose Saving model undefined不是一个函数

[英]Nodejs Mongoose Saving model undefined is not a function

I work with Nodejs Express routes and Mongoose to persist data. 我使用Nodejs Express路由和Mongoose来保存数据。 I did the core routes CRUD operations with no problem. 我做了核心路线CRUD操作没有问题。 However, when I try to perform some operations on one of the fields of the Model and then try to save the Model with model.save it says about .save() method: "undefined is not a function" 但是,当我尝试在Model的某个字段上执行某些操作然后尝试使用model.save保存Model时,它说的是.save()方法:“undefined不是函数”

So, here's the code. 所以,这是代码。 The snippet number (1) works just fine: 片段编号(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);
    });
});

}); });

So the Model has 6 fields: fieldA,..B,..C,..D, myId to identify as index and one field is Array of some values fieldArray. 所以模型有6个字段:fieldA,.. B,.. C,.. D,myId标识为索引,一个字段是一些值的数组fieldArray。 The example above saves the Model, works fine. 上面的例子保存了Model,工作正常。 However if I now try to do something with array field fieldArray and then save the Model it throws me "undefined is not a function" when I use model.save() . 但是,如果我现在尝试使用数组字段fieldArray做一些事情,然后保存模型,当我使用model.save()时,它会抛出“undefined is is a function”。 So the snippet (2) is the code that produces this error: 所以代码段(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);
        });
    });
});

So that thing above throws "undefined is not a function" on using model.save(.. ) 所以上面的东西抛出“undefined不是函数”使用model.save(..)

I also tried second variant of the snippet (2), let's call it snippet (3), incorporating the .exec() Also doesn't work, throws the same "undefined is not a function" on model.save(.. ) So the snippet (3) is this: 我也尝试了片段的第二个变体(2),让我们称它为片段(3),并入.exec()也不起作用,在model.save(...)上抛出相同的“undefined is not a function”所以代码片段(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);
        });
    });
});

I'll be greatful for any inputs and suggestions! 我会很高兴任何意见和建议!

Ansering to the attempt of Willson: 对威尔森的尝试进行了回顾:

Yeah, I know when I call model.find(.. it gives array, if I call model.findOne(.. it gives one object json 是的,我知道当我调用model.find(..它给出数组,如果我调用model.findOne(..它给出一个对象json)

I tried to simplify my example and in my version I actualy did use the: "model[0].fieldArray = newFieldArray" to get the thing from Array fist (the array itself) and then assign to the new value. 我试图简化我的例子,在我的版本中我实际上使用了:“model [0] .fieldArray = newFieldArray”从Array拳头(数组本身)获取东西,然后分配给新值。

The problem still persists, it gives me on model.save(.. "undefined is not a function " ) 问题仍然存在,它给了我model.save(..“undefined不是一个函数”)

The current code is: 目前的代码是:

    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);
        });
    });
});

This snippet (4) above gives on model.save(.. "undefined is not a function" 上面的代码片段(4)给出了model.save(..“undefined不是函数”

When you use in Mongoose the find method, it will return an array since it could discover one or many documents, so in your example you are querying to one specific element by its id, you should grab the first element on the returned array: 当您在Mongoose中使用find方法时,它将返回一个数组,因为它可以发现一个或多个文档,因此在您的示例中,您通过其id查询一个特定元素,您应该获取返回数组上的第一个元素:

Model.find({myId: myId}).exec(function (err, documents) {
            var model = documents[0];

            if (err) throw err;
            var fieldArray = model[0].fieldArray;

Here is an example: 这是一个例子:

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);
    });
  });

});

OK guys! 好,朋友们! I want to thank Wilson Balderrama, because he basically pointed to the right direction. 我要感谢Wilson Balderrama,因为他基本上指出了正确的方向。

The code works! 代码有效! But let me clearify a bit. 但让我澄清一下。

  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);
});

}); });

So basically since the Model.find(.. returns an array 所以基本上是因为Model.find(..返回一个数组
when we save we have to grab the thing from array before saving. 当我们保存时,我们必须在保存之前从数组中获取东西。

So corrected and final working version of my example will be: 我的示例的更正和最终工作版本将是:

    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);
        });
    });
});

Or we can use just Model.findOne(.. to avoid confusing ourselves with this arry return 或者我们可以只使用Model.findOne(...以避免混淆我们自己的回报

In this case we grab directly: 在这种情况下,我们直接抓住:

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);
    });
});
});

So in second case model[0].save(... becomes model.save(... direct grabbing and saving. 所以在第二种情况下模型[0] .save(...变成model.save(......直接抓取并保存)。

Thank you Wilson Balderrama again!! 再次感谢Wilson Balderrama !!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM