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

this context in nested schema required functions changed since mongoose 7.0.2+ #14788

Closed
2 tasks done
skrtheboss opened this issue Aug 2, 2024 · 2 comments · Fixed by #14801
Closed
2 tasks done

this context in nested schema required functions changed since mongoose 7.0.2+ #14788

skrtheboss opened this issue Aug 2, 2024 · 2 comments · Fixed by #14801
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.

Comments

@skrtheboss
Copy link
Contributor

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

8.5.2

Node.js version

20.15.0

MongoDB server version

7.0.0

Typescript version (if applicable)

5.5.4

Description

From Mongoose 7.0.2 onwards, the this context in the required function of nested schemas references the entire parent object, causing incorrect validation behavior.

  • Mongoose Version 7.0.1:

    • The code runs successfully and logs "Post validate".
    • The this context in the required function of prop1 correctly logs the nested schema object.
    • Runkit Example
  • Mongoose Version 7.0.3:

    • The code throws an error during validation.
    • The this context in the required function of prop1 unexpectedly logs the entire parent object, including config.
    • Runkit Example
  • Mongoose Version 8.0.0:

    • The code throws an error during validation.
    • The this context in the required function of prop1 unexpectedly logs the entire parent object, including config.
    • Runkit Example

Observations:

  • In Mongoose 7.0.1, the this context within the required function of prop1 correctly points to the nested schema object.
  • From Mongoose 7.0.2 onwards, the this context unexpectedly includes the parent object, leading to validation errors.

Steps to Reproduce

  1. Run the provided code with Mongoose 7.0.1 and observe the successful validation and logging of "Post validate".
  2. Run the same code with Mongoose 7.0.2 or later versions and observe the validation error and the unexpected this context.
var mongoose = require('mongoose');

function createCustomSchema() {
    return new mongoose.Schema(
        {
            prop1: {
                type: mongoose.Schema.Types.String,
                required() {
                    console.log(this)
                    return this.prop1 === undefined;
                },
                validate: {
                    validator(prop1) {
                        if (this.prop2 !== null && prop1 != null) {
                            throw new Error(`cannot use prop1 if prop2 is defined!`);
                        }
                        return true;
                    },
                },
            },
            prop2: {
                type: mongoose.Schema.Types.String,
                required() {
                    return this.prop2 === undefined;
                },
                validate: {
                    validator(prop2) {
                        if (this.prop1 === null && prop2 === null) {
                            throw new Error(`cannot be null if prop1 is missing!`);
                        }
                        return true;
                    },
                },
            },
        },
        { _id: false },
    );
}

const schema = new mongoose.Schema({
    config: {
        prop: {
            type: createCustomSchema(),
            required: true,
        },
    },
});

const Model = mongoose.model('test-model', schema);

const doc = new Model({
    config: {
        prop: { prop1: null, prop2: 'test-value' },
    },
});

console.log('Pre validate');

await doc.validate()

console.log('Post validate');

Expected Behavior

The this context in the required function of nested schemas should consistently reference the nested schema object, as seen in version 7.0.1.

@IslandRhythms IslandRhythms added the confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. label Aug 7, 2024
@IslandRhythms
Copy link
Collaborator

var mongoose = require('mongoose');

function createCustomSchema() {
    return new mongoose.Schema(
        {
            prop1: {
                type: mongoose.Schema.Types.String,
                required() {
                    console.log(this)
                    return this.prop1 === undefined;
                },
                validate: {
                    validator(prop1) {
                        if (this.prop2 !== null && prop1 != null) {
                            throw new Error(`cannot use prop1 if prop2 is defined!`);
                        }
                        return true;
                    },
                },
            },
            prop2: {
                type: mongoose.Schema.Types.String,
                required() {
                    return this.prop2 === undefined;
                },
                validate: {
                    validator(prop2) {
                        if (this.prop1 === null && prop2 === null) {
                            throw new Error(`cannot be null if prop1 is missing!`);
                        }
                        return true;
                    },
                },
            },
        },
        { _id: false },
    );
}

const schema = new mongoose.Schema({
    config: {
        prop: {
            type: createCustomSchema(),
            required: true,
        },
    },
});

const Model = mongoose.model('test-model', schema);

async function run() {
    await mongoose.connect('mongodb://localhost:27017');
    await mongoose.connection.dropDatabase();
    const doc = new Model({
        config: {
            prop: { prop1: null, prop2: 'test-value' },
        },
    });
    
    console.log('Pre validate');
    
    await doc.validate()
    
    console.log('Post validate');
}

run();

@vkarpov15
Copy link
Collaborator

Looks like this was caused by this commit: dcf7209. Still investigating root cause and potential fixes.

vkarpov15 added a commit that referenced this issue Aug 13, 2024
fix(document): call required functions on subdocuments underneath nested paths with correct context
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