Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Model.findOne not returning docs but returning a wrapper object

I have defined a Model with mongoose like this:

var mongoose = require("mongoose")
var Schema = mongoose.Schema

var userObject = Object.create({
    alias: String,
    email: String,
    password: String,
    updated: { 
        type: Date,
        default: Date.now
    }
})

var userSchema = new Schema(userObject, {strict: false})
var User = mongoose.model('User', userSchema)

module.exports = User

Then I created a user that I can perfectly find through mongo console like this:

db.users.findOne({ email: "[email protected]" });
{
    "_id" : ObjectId("55e97420d82ebdea3497afc7"),
    "password" : "caff3a46ebe640e5b4175a26f11105bf7e18be76",
    "gravatar" : "a4bfba4352aeadf620acb1468337fa49",
    "email" : "[email protected]",
    "alias" : "coco",
    "updated" : ISODate("2015-09-04T10:36:16.059Z"),
    "apps" : [ ],
    "__v" : 0
}

However, when I try to access this object through a node.js with mongoose, the object a retrieve is not such doc, but a wrapper:

This piece of code...

// Find the user for which the login queries
  var User = require('../models/User')
  User.findOne({ email: mail }, function(err, doc) {
    if (err) throw err
      if (doc) {
        console.dir(doc)
        if(doc.password == pass) // Passwords won't match

Produces this output from console.dir(doc)...

{ '$__': 
   { strictMode: false,
     selected: undefined,
     shardval: undefined,
     saveError: undefined,
     validationError: undefined,
     adhocPaths: undefined,
     removing: undefined,
     inserting: undefined,
     version: undefined,
     getters: {},
     _id: undefined,
     populate: undefined,
     populated: undefined,
     wasPopulated: false,
     scope: undefined,
     activePaths: { paths: [Object], states: [Object], stateNames: [Object] },
     ownerDocument: undefined,
     fullPath: undefined,
     emitter: { domain: null, _events: {}, _maxListeners: 0 } },
  isNew: false,
  errors: undefined,
  _doc: 
   { __v: 0,
     apps: [],
     updated: Fri Sep 04 2015 12:36:16 GMT+0200 (CEST),
     alias: 'coco',
     email: '[email protected]',
     gravatar: 'a4bfba4352aeadf620acb1468337fa49',
     password: 'caff3a46ebe640e5b4175a26f11105bf7e18be76',
     _id: { _bsontype: 'ObjectID', id: 'Uét Ø.½ê4¯Ç' } },
  '$__original_validate': { [Function] numAsyncPres: 0 },
  validate: [Function: wrappedPointCut],
  _pres: { '$__original_validate': [ [Object] ] },
  _posts: { '$__original_validate': [] } }

Therefore, passwords won't match because doc.password is undefined.

Why is this caused?

like image 835
jsdario Avatar asked Sep 04 '15 11:09

jsdario


People also ask

What does Mongoose findOne return?

Returns: One document that satisfies the criteria specified as the first argument to this method. If you specify a projection parameter, findOne() returns a document that only contains the projection fields.

What does findOne return Mongoose if not exists?

With NodeJS driver version 4.0 , the Collection#findOne returns an undefined when no match is found. In the earlier driver version 3.6 the same method returned a null . Also, when no document is found it is not an error. If you run the same query in the mongo shell the method returns a null , in case there is no match.

What does findById return Mongoose?

findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .

What is lean Mongoose?

The lean option tells Mongoose to skip hydrating the result documents. This makes queries faster and less memory intensive, but the result documents are plain old JavaScript objects (POJOs), not Mongoose documents.


1 Answers

That's exactly the purpose of mongoose, wrapping mongo objects. It's what provides the ability to call mongoose methods on your documents. If you'd like the simple object, you can call .toObject() or use a lean query if you don't plan on using any mongoose magic on it at all. That being said, the equality check should still hold as doc.password returns doc._doc.password.

like image 171
chrisbajorin Avatar answered Oct 31 '22 09:10

chrisbajorin