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

schema.pre('save' for document not working since 6.1.5 #11257

Closed
alanpurple opened this issue Jan 24, 2022 · 11 comments · Fixed by #12778
Closed

schema.pre('save' for document not working since 6.1.5 #11257

alanpurple opened this issue Jan 24, 2022 · 11 comments · Fixed by #12778
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@alanpurple
Copy link

alanpurple commented Jan 24, 2022

Do you want to request a feature or report a bug?

I can't decide, bug or not?

What is the current behavior?

schema.pre('save', { document: true, query: false }, function (next) {
    const user = this;  // query since 6.1.5, not a document itself

is not working since 6.1.5

If the current behavior is a bug, please provide the steps to reproduce.

{
  "compileOnSave": true,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./",
    "module": "commonjs",
    "moduleResolution": "node",
    "target": "es2020",
    "lib": [ "es2020", "dom" ],
    "resolveJsonModule": true,
    "sourceMap": true
  },
  "exclude": [
    "node_modules"
  ]
}

What is the expected behavior?

"this" should be the document before being saved

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.
nodejs 16.13.2 x64
mongoose 6.1.4(working) 6.1.5~7(not working)
mongodb 5.0.5 x64

> mongoose.version
'6.1.4'

6.1.4 since I rollbacked

@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');

const testSchema = new mongoose.Schema({
    name: String
});

testSchema.pre('save', { document: true, query: false } ,function() {
    console.log('saving ', this);
});

const Test = mongoose.model('Test', testSchema);


async function run() {
    await mongoose.connect('mongodb://localhost:27017');
    await mongoose.connection.dropDatabase();

    const entry = new Test({name: 'Test'});

    await entry.save();
}

run();

@IslandRhythms IslandRhythms added the can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. label Jan 24, 2022
@alanpurple
Copy link
Author

well I checked printed message, but then

this.isNew and this.isModified emit error since 6.1.5

models/project.ts:131:17 - error TS2339: Property 'isNew' does not exist on type 'Query<any, any, {}, any>'.

131     if (project.isNew) {

@vkarpov15 vkarpov15 added this to the 6.1.11 milestone Jan 27, 2022
@vkarpov15 vkarpov15 added needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue typescript Types or Types-test related issue / Pull Request and removed can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. labels Jan 27, 2022
@alanpurple
Copy link
Author

alanpurple commented Feb 3, 2022

@vkarpov15 @IslandRhythms

This is maybe just lack of typescript typings

I've temporarily solved this problem like this

schema.pre('save', { document: true, query: false }, async function (next) {
    const project = this as any;
    assert(project instanceof Document);
    if (project.isNew) {

and this works fine since "this" is a mongoose.document type after all

@IslandRhythms IslandRhythms added can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue labels Feb 4, 2022
@IslandRhythms
Copy link
Collaborator

import { Schema, model, connect, connection } from 'mongoose';

// 1. Create an interface representing a document in MongoDB.
interface User {
  name: string;
  email: string;
  avatar?: string;
}

// 2. Create a Schema corresponding to the document interface.
const schema = new Schema<User>({
  name: { type: String, required: true },
  email: { type: String, required: true },
  avatar: String
});

schema.pre('save', {document: true, query: false}, function() {
    console.log('saving', this)
})
// 3. Create a Model.
const UserModel = model<User>('User', schema);

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

async function run(): Promise<void> {
  // 4. Connect to MongoDB
  await connect('mongodb://localhost:27017/test');
  await connection.dropDatabase();
  const doc = new UserModel({
    name: 'Bill',
    email: 'bill@initech.com',
    avatar: 'https://i.imgur.com/dM7Thhn.png'
  });
  await doc.save();
}

@IslandRhythms IslandRhythms removed the can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. label Feb 4, 2022
@alanpurple
Copy link
Author

@IslandRhythms

use this.isNew

@vkarpov15
Copy link
Collaborator

@alanpurple can you please clarify what your most recent comment means?

@alanpurple
Copy link
Author

well I checked printed message, but then

this.isNew and this.isModified emit error since 6.1.5

models/project.ts:131:17 - error TS2339: Property 'isNew' does not exist on type 'Query<any, any, {}, any>'.

131     if (project.isNew) {

@vkarpov15 check this error

@IslandRhythms
Copy link
Collaborator

@vkarpov15

import { Schema, model, connect, connection, Query, Document } from 'mongoose';

// 1. Create an interface representing a document in MongoDB.
interface User {
  name: string;
  email: string;
  avatar?: string;
}

// 2. Create a Schema corresponding to the document interface.
const schema = new Schema<User>({
  name: { type: String, required: true },
  email: { type: String, required: true },
  avatar: String
});

schema.pre('save', {document: true, query: false}, function() {
    console.log('saving', this);
    console.log('Is this a Document?', this instanceof Document, 'Is this a Query?', this instanceof Query);
    console.log(this.$__); // says property $__ does not exist on type Query<any,any, {}, any> on 6.1.5 and up, returns a value below.
});
// 3. Create a Model.
const UserModel = model<User>('User', schema);

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

async function run(): Promise<void> {
  // 4. Connect to MongoDB
  await connect('mongodb://localhost:27017/test');
  await connection.dropDatabase();
  const doc = new UserModel({
    name: 'Bill',
    email: 'bill@initech.com',
    avatar: 'https://i.imgur.com/dM7Thhn.png'
  });
  await doc.save();
}

@IslandRhythms
Copy link
Collaborator

Yes, I left a note in the script for vkarpov15 when he comes to check it out.

@alanpurple
Copy link
Author

@IslandRhythms

sorry for my misunderstanding

@alanpurple
Copy link
Author

@vkarpov15
@IslandRhythms

this happens again with 6.7.2

only with 'updateOne'

Schema.pre('updateOne', { document: true, query: false }

@vkarpov15 vkarpov15 reopened this Nov 23, 2022
@vkarpov15 vkarpov15 modified the milestones: 6.2.3, 6.7.5 Nov 23, 2022
@vkarpov15 vkarpov15 added the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Nov 23, 2022
@vkarpov15 vkarpov15 added confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Dec 5, 2022
vkarpov15 added a commit that referenced this issue Dec 8, 2022
vkarpov15 added a commit that referenced this issue Dec 19, 2022
fix(types): correctly infer `this` when using `pre('updateOne')` with `{ document: true, query: false }`
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. typescript Types or Types-test related issue / Pull Request
Projects
None yet
3 participants