Mongoose/MongoDB result fields appear undefined in

2020-01-25 01:10发布

Is there something that I'm missing that would allow item to log as an object with a parameter, but when I try to access that parameter, it's undefined?

What I've tried so far:

  • console.log(item) => { title: "foo", content: "bar" } , that's fine
  • console.log(typeof item) => object
  • console.log(item.title) => "undefined"

I'll include some of the context just in case it's relevant to the problem.

var TextController = function(myCollection) {
  this.myCollection = myCollection
}

TextController.prototype.list = function(req, res, next) {
  this.myCollection.find({}).exec(function(err, doc) {
    var set = new Set([])
    doc.forEach(function(item) {
      console.log(item)         // Here item shows the parameter
      console.log(item.title)   // "undefined"
      set.add(item.title)       
    })
    res.json(set.get());
  })
}

Based on suggestion I dropped debugger before this line to check what item actually is via the node repl debugger. This is what I found : http://hastebin.com/qatireweni.sm

From this I tried console.log(item._doc.title) and it works just fine.. So, this seems more like a mongoose question now than anything.

There are questions similar to this, but they seem to be related to 'this' accessing of objects or they're trying to get the object outside the scope of the function. In this case, I don't think I'm doing either of those, but inform me if I'm wrong. Thanks

10条回答
乱世女痞
2楼-- · 2020-01-25 01:47

A better way to tackle an issue like this is using doc.toObject() like this

doc.toObject({ getters: true })

other options include:

  • getters: apply all getters (path and virtual getters)
  • virtuals: apply virtual getters (can override getters option)
  • minimize: remove empty objects (defaults to true)
  • transform: a transform function to apply to the resulting document before returning
  • depopulate: depopulate any populated paths, replacing them with their original refs (defaults to false)
  • versionKey: whether to include the version key (defaults to true)

so for example you can say

Model.findOne().exec((err, doc) => {
   if (!err) {
      doc.toObject({ getters: true })
      console.log('doc _id:', doc._id) // or title
   }
})

and now it will work

查看更多
我只想做你的唯一
3楼-- · 2020-01-25 01:48

I think using 'find' method returns an array of Documents.I tried this and I was able to print the title

for (var i = 0; i < doc.length; i++) {
   console.log("iteration " + i);
   console.log('ID:' + docs[i]._id);
   console.log(docs[i].title);
}
查看更多
Deceive 欺骗
4楼-- · 2020-01-25 01:51

Make sure that you have defined title in your schema:

var MyCollectionSchema = new mongoose.Schema({
    _id: String,
    title: String
});
查看更多
家丑人穷心不美
5楼-- · 2020-01-25 01:52

Use findOne() instead of find().

The find() method returns an array of values, even if you have only one possible result, you'll need to use item[0] to get it.

The findOne method returns one object or none, then you'll be able to access its properties with no issues.

查看更多
登录 后发表回答