Home > other >  Mongoose FindOne returns query and collection instead of document from collection
Mongoose FindOne returns query and collection instead of document from collection

Time:01-03

I am new to NodeJS and trying to work on mongoose for my college project,I have been trying to retrieve a document from the collection using the model.findOne() method but, instead of returning a document from the collection, mongoose instead returns a query and model metadata.

adding await before userModel.findOne() simply results in query already executed error from mongoose.

User Schema

var mongoose = require('mongoose');

//Define Collection Schema
const userSchema = new mongoose.Schema({
    emailId:{
        type: String,
        required: true
    },

    userName:{
        type: String,
        required: true
    },

    password:{
        type: String,
        required: true
    },

    role:{
        type: String,
        required: true,
        default: "user"
    },
    
    playlist:[{
        type: String,
        type: mongoose.Schema.Types.ObjectId,
        ref: "vidmodel"
    }],

    likes:[{
        type: String,
        type: mongoose.Schema.Types.ObjectId,
        ref: "vidmodel"
    }],

    dislikes:[{
        type:  String,
        type: mongoose.Schema.Types.ObjectId,
        ref: "vidmodel"
    }]
})

userSchema.pre('save', function(next) {
    this.emailId=this.emailId.toLowerCase();
    next();
})

module.exports = mongoose.model('usermodel', userSchema)

Function

const userModel = require('./models/userModel')

app.post('/user/signup', upload.single(''), async(req,res)=>{
    try{
        const formData = req.body
        const email = formData.email
        const password = formData.password
        existingUser=userModel.findOne({emailId:email}, function(err, user){
            if(user){
                console.log("output of findOne",user)
            }
            if(err){
                console.log(err)
            }
        })
        if(existingUser){
            console.log(existingUser)
        }
    }
    catch(err){
        console.log(err)
    }
})

Output:

Query {
  _mongooseOptions: {},
  _transforms: [],
  _hooks: Kareem { _pres: Map(0) {}, _posts: Map(0) {} },
  _executionStack: null,
  mongooseCollection: Collection {
    collection: Collection { s: [Object] },
    Promise: [Function: Promise],
    modelName: 'usermodel',
    _closed: false,
    opts: {
      autoIndex: true,
      autoCreate: true,
      schemaUserProvidedOptions: {},
      capped: false,
      Promise: [Function: Promise],
      '$wasForceClosed': undefined
    },
    name: 'usermodels',
    collectionName: 'usermodels',
    conn: NativeConnection {
      base: [Mongoose],
      collections: [Object],
      models: [Object],
      config: {},
      replica: false,
      options: null,
      otherDbs: [],
      relatedDbs: {},
      states: [Object: null prototype],
      _readyState: 1,
      _closeCalled: undefined,
      _hasOpened: true,
      plugins: [],
      id: 0,
      _queue: [],
      _listening: false,
      _connectionString: 'mongodb://localhost/streambytes-dev',
      _connectionOptions: [Object],
      client: [MongoClient],
      '$initialConnection': [Promise],
      db: [Db],
      host: 'localhost',
      port: 27017,
      name: 'streambytes-dev'
    },
    queue: [],
    buffer: false,
    emitter: EventEmitter {
      _events: [Object: null prototype] {},
      _eventsCount: 0,
      _maxListeners: undefined,
      [Symbol(kCapture)]: false
    }
  },
  model: Model { usermodel },
  schema: Schema {
    obj: {
      emailId: [Object],
      userName: [Object],
      password: [Object],
      role: [Object],
      playlist: [Array],
      likes: [Array],
      dislikes: [Array]
    },
    paths: {
      emailId: [SchemaString],
      userName: [SchemaString],
      password: [SchemaString],
      role: [SchemaString],
      playlist: [SchemaArray],
      likes: [SchemaArray],
      dislikes: [SchemaArray],
      _id: [ObjectId],
      __v: [SchemaNumber]
    },
    aliases: {},
    subpaths: {
      'playlist.$': [ObjectId],
      'likes.$': [ObjectId],
      'dislikes.$': [ObjectId]
    },
    virtuals: { id: [VirtualType] },
    singleNestedPaths: {},
    nested: {},
    inherits: {},
    callQueue: [],
    _indexes: [],
    methods: {},
    methodOptions: {},
    statics: {},
    tree: {
      emailId: [Object],
      userName: [Object],
      password: [Object],
      role: [Object],
      playlist: [Array],
      likes: [Array],
      dislikes: [Array],
      _id: [Object],
      __v: [Function: Number],
      id: [VirtualType]
    },
    query: {},
    childSchemas: [],
    plugins: [ [Object], [Object], [Object], [Object], [Object] ],
    '$id': 3,
    mapPaths: [],
    s: { hooks: [Kareem] },
    _userProvidedOptions: {},
    options: {
      typeKey: 'type',
      id: true,
      _id: true,
      validateBeforeSave: true,
      read: null,
      shardKey: null,
      discriminatorKey: '__t',
      autoIndex: null,
      minimize: true,
      optimisticConcurrency: false,
      versionKey: '__v',
      capped: false,
      bufferCommands: true,
      strictQuery: true,
      strict: true,
      pluralization: true
    },
    '$globalPluginsApplied': true
  },
  op: 'findOne',
  options: {},
  _conditions: { emailId: '[email protected]' },
  _fields: undefined,
  _update: undefined,
  _path: undefined,
  _distinct: undefined,
  _collection: NodeCollection {
    collection: Collection {
      collection: [Collection],
      Promise: [Function: Promise],
      modelName: 'usermodel',
      _closed: false,
      opts: [Object],
      name: 'usermodels',
      collectionName: 'usermodels',
      conn: [NativeConnection],
      queue: [],
      buffer: false,
      emitter: [EventEmitter]
    },
    collectionName: 'usermodels'
  },
  _traceFunction: undefined,
  '$useProjection': true
}

I tried using callback which does not result in anything, tried the code mentioned in the question which simply results in query and model metadata as the output. using async keyword before findOne simply results in query already executed error. I cannot figure out what is the problem here.

CodePudding user response:

Try to use async/await like this :

 app.post('/user/signup', upload.single(''), async(req,res)=>{
     try{
         const formData = req.body
         const email = formData.email
         const password = formData.password
         const user = await userModel.findOne({emailId: email}).exec();
             
             if(user){
                console.log("output of findOne", user)
              // your response logic
             } else {
               console.log("User does not existe") 
             // your response logic
             }
     }catch(err){
         console.log(err)
     });

You can choose to use callback or Async/await syntax with try/catch, but not mix together in the single function since the callback will handle his own error, anyway it's better to use async/await if you can it's much more easy to read.

you can check mongoose documentation : https://mongoosejs.com/docs/api.html#model_Model-findOne

CodePudding user response:

Turns out query was correctly written but for some reason, VS Code refused to identify the email variable which supplied the value for emailId field. even though the variable did contain proper value, it wasn't being passed to findOne(). simply shutting down the system yesterday and starting it today solved the issue

although why it kept returning query is still unclear to me, might be due not being able to find a document made it return query instead

  • Related