Mongoose/MongoDB result fields appear undefined in Javascript

前端 未结 10 2223
囚心锁ツ
囚心锁ツ 2020-11-27 20:13

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

相关标签:
10条回答
  • 2020-11-27 20:44

    Try performing a for in loop over item and see if you can access values.

    for (var k in item) {
        console.log(item[k]);
    }
    

    If it works, it would mean your keys have some non-printable characters or something like this.

    From what you said in the comments, it looks like somehow item is an instance of a String primitive wrapper.

    E.g.

    var s = new String('test');
    typeof s; //object
    s instanceof String; //true
    

    To verify this theory, try this:

    eval('(' + item + ')').title;
    

    It could also be that item is an object that has a toString method that displays what you see.

    EDIT: To identify these issues quickly, you can use console.dir instead of console.log, since it display an interactive list of the object properties. You can also but a breakpoint and add a watch.

    0 讨论(0)
  • 2020-11-27 20:45

    Solution

    You can call the toObject method in order to access the fields. For example:

    var itemObject = item.toObject();
    console.log(itemObject.title); // "foo"
    

    Why

    As you point out that the real fields are stored in the _doc field of the document.

    But why console.log(item) => { title: "foo", content: "bar" }?

    From the source code of mongoose(document.js), we can find that the toString method of Document call the toObject method. So console.log will show fields 'correctly'. The source code is shown below:

    var inspect = require('util').inspect;
    
    ...
    
    /**
     * Helper for console.log
     *
     * @api public
     */
    Document.prototype.inspect = function(options) {
      var isPOJO = options &&
        utils.getFunctionName(options.constructor) === 'Object';
      var opts;
      if (isPOJO) {
        opts = options;
      } else if (this.schema.options.toObject) {
        opts = clone(this.schema.options.toObject);
      } else {
        opts = {};
      }
      opts.minimize = false;
      opts.retainKeyOrder = true;
      return this.toObject(opts);
    };
    
    /**
     * Helper for console.log
     *
     * @api public
     * @method toString
     */
    
    Document.prototype.toString = function() {
      return inspect(this.inspect());
    };
    
    0 讨论(0)
  • 2020-11-27 20:45

    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.

    0 讨论(0)
  • 2020-11-27 20:51

    Old question, but since I had a problem with this too, I'll answer it.
    This probably happened because you're using find() instead of findOne(). So in the end, you're calling a method for an array of documents instead of a document, resulting in finding an array and not a single document. Using findOne() will let you get access the object normally.

    0 讨论(0)
提交回复
热议问题