Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model.create Promise resolved although no document saved #6080

Closed
CodeurSauvage opened this issue Feb 1, 2018 · 3 comments
Closed

Model.create Promise resolved although no document saved #6080

CodeurSauvage opened this issue Feb 1, 2018 · 3 comments

Comments

@CodeurSauvage
Copy link

CodeurSauvage commented Feb 1, 2018

Hello everyone,

I'm using mongoose version 5.0.3 and node version 9.4.0. According to mongoose documentation model.create should return a promise which, I assume, is resolved as the document created is saved in the DB. However as shown by the code below it seems that the promise is resolved before the document is saved in the DB.

async function test(){
    
    let schema = new mongoose.Schema({a: String});

    let model = mongoose.model('test', schema);
    
    await model.remove({}).exec();

    await model.create({ a: 'test'}, 
       (err,result)=> {console.log('created');});
    
    await model.findOneAndUpdate(
        { a : 'test' } , 
        { a: 'newValue'}
    )
    .exec((err, result) => {
        console.log('update : '+result);
    });
    
    await model.find({a: 'test'},(err,result) => {
        console.log(result); 
    });
    
}

output in terminal : 
    update : null
    found :
    created

findOneAndUpdate do not find any document. In addition to that "created" is appearing at the end in the terminal, hence the callback of the create method is executed as if the await was not waiting for the async task 'create' to be done.

However by adding a promise which is resolved once the callback of create is triggered, as shown below, we obtain the expected result :

async function test(){
    
    let schema = new mongoose.Schema({a: String});

    let model = mongoose.model('test', schema);
    
    await model.remove({}).exec();

    await new Promise((resolve,reject) => {
        model.create({ a: 'test'}, 
       (err,result)=> {
            console.log('created');
            resolve();
        });
    });
    
    await model.findOneAndUpdate(
        { a : 'test' } , 
        { a: 'newValue'}
    )
    .exec((err, result) => {
        console.log('update : '+result);
    });
    
    await model.find({a: 'newValue'},(err,result) => {
        console.log('found : ' +result); 
    });
    
}

output in terminal: 
     created
     update : { _id: 5a735fbc1fe826233014d62d, a: 'test', __v: 0 }
     found : { _id: 5a735fbc1fe826233014d62d, a: 'newValue', __v: 0 }

Now we have the expected result.

All functions which operate on the DB do return a promise that if resolved indicates that the operation has been done, specifically Query. I assume that was also the case of model.create although it doesnt return a query object strictly speaking. I also wonder what the fulfilled returned promise means as it does not show that the doc was created in the DB. Perhaps I missed the whole point but I find it a bit ambiguous

@lineus
Copy link
Collaborator

lineus commented Feb 2, 2018

I believe I remember reading in the 4.x docs that if you pass a callback to model.create it doesn't return a promise.

let x = model.create({ a: 'test' }, () => {})
  x.then(console.log(x)) //TypeError: Cannot read property 'then' of undefined

if you pull out the callback:

let x = model.create({ a: 'test' })
  x.then(console.log(x)) // Promise { <pending> }

the 5.x source for model.js bears this out calling utils.promiseOrCallback

@sobafuchs
Copy link
Contributor

Yup, @lineus is correct, can I close out this issue @CodeurSauvage ?

@vkarpov15
Copy link
Collaborator

@CodeurSauvage @lineus is correct, mongoose 5 does not return a promise if a callback is specified. Your script works if you replace:

    await model.create({ a: 'test'}, 
       (err,result)=> {console.log('created');});

With:

    await model.create({ a: 'test'}).then(result => console.log('created'));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants