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

mongoose updateOne add pre then no return #12836

Closed
1 task done
tingfeima opened this issue Dec 26, 2022 · 3 comments · Fixed by mongoosejs/kareem#36 or #12881
Closed
1 task done

mongoose updateOne add pre then no return #12836

tingfeima opened this issue Dec 26, 2022 · 3 comments · Fixed by mongoosejs/kareem#36 or #12881
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@tingfeima
Copy link

tingfeima commented Dec 26, 2022

Prerequisites

  • I have written a descriptive issue title

Mongoose version

6.5.1

Node.js version

v14.17.3

MongoDB version

4.2

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

12.4

Issue

  schema.pre('updateOne',async function (doc, next) {
    const updateInfo = {}
    // do stuff...
    this._update.$set = { ...updateInfo }
    return next()
  })
  const result = await model.updateOne(
    {
     nickname:'mark',
    },
    { $set: { updatedAt:new Date() } }
  )
  console.log(result)  // undefined

why the result is undefined

@tingfeima tingfeima added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary help wanted labels Dec 26, 2022
@eternalbasic1
Copy link

I guess, As you are using await and async and javascript is a Single-Threaded & Synchronous Language it just execute the code line by line very fast. As you are using async and await which internally deals with Event loop/ TaskQueue/MicroTask. Just waiting for call stack to empty. Why don't you make a the console.log inside a settimeout function and see it, I feel it works when you use a
settimeout(console.log(result),2000);
at the last line

@vkarpov15 vkarpov15 added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary help wanted labels Dec 29, 2022
@vkarpov15 vkarpov15 added this to the 6.8.3 milestone Dec 29, 2022
@vkarpov15
Copy link
Collaborator

The following prints undefined. But prints an update result object if you remove the next() call. Strange.

'use strict';

const mongoose = require('mongoose');
mongoose.set('debug', true);

const schema = mongoose.Schema({ name: String });
schema.pre('updateOne', async function(doc, next) {
  this._update = this._update || {};
  this._update.$set = { name: 'foo' };
  //return next();
  next();
});
const Test = mongoose.model('Test', schema);

run().catch(err => console.log(err));

async function run() {
  await mongoose.connect('mongodb://localhost:27017/mongoose_test');
  const res = await Test.updateOne();
  console.log(res);
  process.exit(0);
}

@vkarpov15
Copy link
Collaborator

The issue is that next is the first parameter to pre hooks, not the second. Do the following instead and it will work fine:

schema.pre('updateOne',async function (next) { // <-- remove `doc` as first parameter here
  const updateInfo = {}
  // do stuff...
  this._update.$set = { ...updateInfo }
  return next()
})

The issue is that Mongoose calls the updateOne hook with next as the first argument, and the final callback that it should call once all hooks are done as the 2nd argument. Admittedly this is not a great design choice, and mongoosejs/kareem#36 fixes that. But, in the meantime, please fix your argument order and this will work fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
3 participants