8

I am attemping to run a mongoose.findOne on my data base but I get unexpected results.My query is

const User = mongoose.model('User', {name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array })


exports.findUser = function findUser(email){

    const foundUser = User.findOne({email: email}, function(err, userObj){
        if(err){
            return err
        }       else if (userObj){
            return userObj
        }       else{
            return null
        }
    })

    return foundUser
}

however this returns the following data (seemingly random?) and has none of the data that I requested

Query {
  _mongooseOptions: {},
  mongooseCollection: 
   NativeCollection {
     collection: null,
     opts: { bufferCommands: true, capped: false },
     name: 'users',
     collectionName: 'users',
     conn: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'ds113938.mlab.com',
        port: 13938,
        user: 'root',
        pass: 'root',
        name: 'users',
        options: [Object],
        otherDbs: [],
        _readyState: 2,
        _closeCalled: false,
        _hasOpened: false,
        _listening: false,
        db: [Object] },
     queue: [],
     buffer: true,
     emitter: 
      EventEmitter {
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined } },
  model: 
   { [Function: model]
     hooks: Kareem { _pres: {}, _posts: {} },
     base: 
      Mongoose {
        connections: [Object],
        plugins: [],
        models: [Object],
        modelSchemas: [Object],
        options: [Object] },
     modelName: 'User',
     model: [Function: model],
     db: 
      NativeConnection {
        base: [Object],
        collections: [Object],
        models: [Object],
        config: [Object],
        replica: false,
        hosts: null,
        host: 'ds113938.mlab.com',
        port: 13938,
        user: 'root',
        pass: 'root',
        name: 'users',
        options: [Object],
        otherDbs: [],
        _readyState: 2,
        _closeCalled: false,
        _hasOpened: false,
        _listening: false,
        db: [Object] },
     discriminators: undefined,
     schema: 
      Schema {
        obj: [Object],
        paths: [Object],
        subpaths: {},
        virtuals: [Object],
        singleNestedPaths: {},
        nested: {},
        inherits: {},
        callQueue: [Object],
        _indexes: [],
        methods: {},
        statics: {},
        tree: [Object],
        _requiredpaths: undefined,
        discriminatorMapping: undefined,
        _indexedpaths: undefined,
        query: {},
        childSchemas: [],
        s: [Object],
        options: [Object],
        '$globalPluginsApplied': true },
     collection: 
      NativeCollection {
        collection: null,
        opts: [Object],
        name: 'users',
        collectionName: 'users',
        conn: [Object],
        queue: [],
        buffer: true,
        emitter: [Object] },
     Query: { [Function] base: [Object] },
     '$__insertMany': [Function],
     insertMany: [Function] },
  schema: 
   Schema {
     obj: 
      { name: [Function: String],
        email: [Function: String],
        passwordHash: [Function: String],
        validation: [Function: String],
        validationCode: [Function: String],
        favorites: [Function: Array] },
     paths: 
      { name: [Object],
        email: [Object],
        passwordHash: [Object],
        validation: [Object],
        validationCode: [Object],
        favorites: [Object],
        _id: [Object],
        __v: [Object] },
     subpaths: {},
     virtuals: { id: [Object] },
     singleNestedPaths: {},
     nested: {},
     inherits: {},
     callQueue: [ [Object], [Object], [Object], [Object] ],
     _indexes: [],
     methods: {},
     statics: {},
     tree: 
      { name: [Function: String],
        email: [Function: String],
        passwordHash: [Function: String],
        validation: [Function: String],
        validationCode: [Function: String],
        favorites: [Function: Array],
        _id: [Object],
        id: [Object],
        __v: [Function: Number] },
     _requiredpaths: undefined,
     discriminatorMapping: undefined,
     _indexedpaths: undefined,
     query: {},
     childSchemas: [],
     s: { hooks: [Object], kareemHooks: [Object] },
     options: 
      { retainKeyOrder: false,
        typeKey: 'type',
        id: true,
        noVirtualId: false,
        _id: true,
        noId: false,
        validateBeforeSave: true,
        read: null,
        shardKey: null,
        autoIndex: null,
        minimize: true,
        discriminatorKey: '__t',
        versionKey: '__v',
        capped: false,
        bufferCommands: true,
        strict: true,
        pluralization: true },
     '$globalPluginsApplied': true },
  op: 'findOne',
  options: { retainKeyOrder: false },
  _conditions: { email: 'Adam@gmail.com' },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: 
   NodeCollection {
     collection: 
      NativeCollection {
        collection: null,
        opts: [Object],
        name: 'users',
        collectionName: 'users',
        conn: [Object],
        queue: [],
        buffer: true,
        emitter: [Object] },
     collectionName: 'users' },
  _traceFunction: undefined,
  _castError: null,
  _count: [Function],
  _execUpdate: [Function],
  _find: [Function],
  _findOne: [Function],
  _findOneAndRemove: [Function],
  _findOneAndUpdate: [Function] }

I was wondering how to fix this, this seems to be an overview of the query that I am attempting to run and not the results of said query

Dan O
  • 6,022
  • 2
  • 32
  • 50
Jack Tidbury
  • 183
  • 1
  • 1
  • 12

6 Answers6

8

Try this:

const User = mongoose.model('User', {name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array })


exports.findUser = function findUser(email, callback){
    User.findOne({email: email}, function(err, userObj){
        if(err){
            return callback(err);
        } else if (userObj){
            return callback(null,userObj);
        } else {
            return callback();
        }
    });
}

When you execute User.findOne, the mongoose calls the mongodb and return your user in the callback (last param in your findOne function) so can return the found user calling the callback.

To call the findUser function, you needs to pass a callback, something like this:

findUser('adam@gmail.com', function(error, userFound) {
   console.log(userFound);
});

You can find more details about Mongoose findOne here and to learn about callback functions you can take a look here

Community
  • 1
  • 1
danilodeveloper
  • 3,840
  • 2
  • 36
  • 56
  • damn, 9 seconds faster :D – xShirase Nov 30 '16 at 20:26
  • @xShirase, the most funny is that our answers is very similar. haha – danilodeveloper Nov 30 '16 at 20:29
  • well yeah, there's not a million ways to do a mongoose query :) Although mine is more detailed and I used ES6 arrow functions because OP used const. I WIN! – xShirase Nov 30 '16 at 20:30
  • I attempted to impliment this as you put. But when i call it i recive the error of TypeError: callback is not a function. I am calling it as finduser('adam@gmail.com') is this correct. Or how do i impliment the callback? – Jack Tidbury Nov 30 '16 at 20:35
  • you needs to call `findUser('adam@gmail.com', function(error, userFound){console.log(userFound);})` so you will see the user found. – danilodeveloper Nov 30 '16 at 20:38
3

What you're seeing is the result of return foundUser, a Mongoose Query object.

You are mixing synchronous and asynchronous code, you have to wait for your query to be executed and callback to the function that called it, like so :

const User = mongoose.model('User', {name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array });

exports.findUser = function findUser(email,callback){
    const foundUser = User.findOne({email: email}, (err, userObj)=>{
        if(err){
            callback(err)
        } else if (userObj){
            callback(null,userObj)
        } else {
            callback(new Error('Some strange thing has happened));
        }
    });
}

You then call your function like this :

findUser((err,user)=>{
    if(err) console.log(err);
    console.log(user)
});

For a quick intro to callbacks, this is the link to start with What is a callback function?

Community
  • 1
  • 1
xShirase
  • 11,975
  • 4
  • 53
  • 85
1

I had the same problem recently.

In my case, a solution was made before running, although in this case the method has to be asynchronous.

It follows below:

async findUser(email,callback){
    const foundUser = await User.findOne({email: email}, (err, userObj)=>{
        if(err){
            callback(err)
        } else if (userObj){
            callback(null,userObj)
        } else {
            callback(new Error('Some strange thing has happened));
        }
    });
}
1

Just modify what you have already to this...

{
  ...
  return foundUser.toJSON();
}

This will return the actual document/value (without the meta data of Query).

0

The issue is that you are returning the foundUser object even before the query completes. That's why you get query object as the response instead of a document object.

THE CODE WITH ERROR ` const User = mongoose.model('User', {name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array })

exports.findUser = function findUser(email){

const foundUser = User.findOne({email: email}, function(err, userObj){
    if(err){
        return err
    }       else if (userObj){
        return userObj
    }       else{
        return null
    }
})

return foundUser

} `

CODE WITHOUT ERROR const User = mongoose.model('User', {name: String, email: String, passwordHash: String, validation: String, validationCode: String, favorites: Array })

exports.findUser = function findUser(email){

const foundUser = User.findOne({email: email}, function(err, userObj){
    if(err){
        return err
    }       else if (userObj){
        return userObj
    }       else{
        return null
    }
})

}

George
  • 321
  • 3
  • 5
0
exports.findUser = async function findUser(email){
  const foundUser = await User.findOne({email: email}, function(err, userObj){
    if (err) {
      return err
    } else if (userObj) {
      return userObj
    } else {
      return null
    }
  })
  return foundUser
}
Tyler2P
  • 2,324
  • 26
  • 22
  • 31