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

Dynamic virtual populate not working on subdocument with separate schema #12363

Open
2 tasks done
Hybrid-Force opened this issue Aug 31, 2022 · 3 comments · May be fixed by #12440
Open
2 tasks done

Dynamic virtual populate not working on subdocument with separate schema #12363

Hybrid-Force opened this issue Aug 31, 2022 · 3 comments · May be fixed by #12440
Labels
discussion If you have any thoughts or comments on this issue, please share them!

Comments

@Hybrid-Force
Copy link

Prerequisites

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

Mongoose version

6.5.4

Node.js version

16.15.0

MongoDB server version

4.2.1

Description

Seems to be related to #8277 and #8742

When using dynamic ref on child schema { ref: (doc) => doc.refType }, the passed in doc is the parent document, not the subdocument, causing dynamic ref path not correctly returned.

I tried both virtuals option in schema constructor options and schema virtual() method, tried both ref and refPath in virtual options, none works.

Steps to Reproduce

import mongoose from 'mongoose';
import { expect } from 'chai';

const nestedSchema = new mongoose.Schema({
    targetType: String,
    targetId: mongoose.Schema.Types.ObjectId,
}, {
    virtuals: {
        target: {
            options: {
                ref: (doc: any) => {
                    // doc should be the sub document
                    // but instead, it is the parent document
                    console.debug(doc);
                    return doc.targetType;
                },
                localField: 'targetId',
                foreignField: '_id',
                justOne: true,
            }
        }
    }
});

const parentSchema = new mongoose.Schema({
    nested: {
        type: nestedSchema
    },
});

const NestedDynamicVirtualPopulateTest = mongoose.model('NestedDynamicVirtualPopulateTest', parentSchema);

await NestedDynamicVirtualPopulateTest.collection.drop();
const target = new NestedDynamicVirtualPopulateTest({});
await target.save();

const parent = new NestedDynamicVirtualPopulateTest({
    nested: {
        targetType: (target.constructor as typeof NestedDynamicVirtualPopulateTest).modelName,
        targetId: target._id,
    }
});
await parent.save();
await parent.populate('nested.target');
// @ts-ignore
expect(parent.nested.target).to.exist;

Expected Behavior

Since the virtual is defined on the child schema, the dynamic ref path should be relative to the subdocument, not the parent document.

@IslandRhythms IslandRhythms added the typescript Types or Types-test related issue / Pull Request label Aug 31, 2022
@IslandRhythms
Copy link
Collaborator

image

12363.ts:49:29 - error TS2551: Property 'target' does not exist on type '{ targetType?: {}; targetId?: { toString: any; _bsontype?: { toString: {}; _bsontype?: ObjectId; inspect?: {}; equals?: {}; _id?: ...; id?: { [x: number]: unknown; [toStringTag]?: unknown; [iterator]?: {}; toString: {}; ... 100 more ...; byteOffset?: unknown; }; toHexString?: {}; toJSON?: {}; generationTime?: unknow...'. Did you mean 'targetId'?

49   console.log(parent.nested.target);
                               ~~~~~~

node_modules/mongoose/types/query.d.ts:619:29 - error TS2304: Cannot find name 'this'.

619     toConstructor(): typeof this;
                                ~~~~


Found 2 errors.
import mongoose from 'mongoose';

const nestedSchema = new mongoose.Schema({
    targetType: String,
    targetId: mongoose.Schema.Types.ObjectId,
}, {
    virtuals: {
        target: {
            options: {
                ref: (doc: any) => {
                    // doc should be the sub document
                    // but instead, it is the parent document
                    console.debug(doc);
                    return doc.targetType;
                },
                localField: 'targetId',
                foreignField: '_id',
                justOne: true,
            }
        }
    }
});

const parentSchema = new mongoose.Schema({
    nested: {
        type: nestedSchema
    },
});

const NestedDynamicVirtualPopulateTest = mongoose.model('NestedDynamicVirtualPopulateTest', parentSchema);
async function run() {
  await mongoose.connect('mongodb://localhost:27017');
  await mongoose.connection.dropDatabase();
  const target = new NestedDynamicVirtualPopulateTest({});
  await target.save();

  const parent = new NestedDynamicVirtualPopulateTest({
      nested: {
          targetType: (target.constructor as typeof NestedDynamicVirtualPopulateTest).modelName,
          targetId: target._id,
      }
  });
  await parent.save();
  await parent.populate('nested.target');
  console.log(parent);
  console.log('=============');
  console.log(parent.nested);
  console.log('=================');
  console.log(parent.nested.target);
  console.log('======================')
}

run();

@Hybrid-Force
Copy link
Author

Hi @IslandRhythms, the code snippet in my initial comment was not properly typed, because I thought the type definition does not do much help demonstrating the issue and will make the snippet unnecessarily long. So I just put @ts-ignore before the parent.nested.target part to avoid typing errors :)

@Hybrid-Force
Copy link
Author

Hi @IslandRhythms, I think the "typescript" label on this issue is not appropriate. The typing error in your comment is not related to this issue. And this issue is not related to typescript.

Hybrid-Force added a commit to Hybrid-Force/mongoose that referenced this issue Sep 17, 2022
@Hybrid-Force Hybrid-Force linked a pull request Sep 17, 2022 that will close this issue
@vkarpov15 vkarpov15 added discussion If you have any thoughts or comments on this issue, please share them! and removed typescript Types or Types-test related issue / Pull Request labels Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion If you have any thoughts or comments on this issue, please share them!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants