mongoose-autopopulate
mongoose-autopopulate copied to clipboard
can't use mongoose-autopopulate on recursively nested schema : Maximum call stack size exceeded
Hello !
First of all, thanks for mongoose & mongoose-autopopulate. I tried to reduce my example to its simplest form. I'm using Nestjs as backend framework.
Reproduction schema is following:
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import {
Document as MongooseDocument,
Schema as MongooseSchema,
} from 'mongoose';
interface SectionI {
template?: SectionTemplateI;
text: string;
date: Date;
subSections?: SectionI[];
}
interface SectionTemplateI {
section: SectionI;
}
export type SectionDocument = Section & MongooseDocument;
@Schema()
export class Section implements SectionI {
@Prop({
type: MongooseSchema.Types.ObjectId,
ref: 'SectionTemplate',
autopopulate: false,
required: false,
})
template?: SectionTemplateI;
@Prop({ type: String, required: true })
text: string;
@Prop({ type: Date, required: true })
date: Date;
subSections?: SectionI[];
}
export const SectionSchema = SchemaFactory.createForClass(Section);
SectionSchema.add({
subSections: {
type: [SectionSchema],
required: false,
},
});
export type SectionTemplateDocument = SectionTemplate & MongooseDocument;
@Schema()
export class SectionTemplate implements SectionTemplateI {
@Prop({ type: SectionSchema, required: true })
section: SectionI;
}
export const SectionTemplateSchema =
SchemaFactory.createForClass(SectionTemplate);
As you can see, subSections
are nested, not relations. I believe it's the root cause of this issue, but don't know if it's expected behavior, and if so, what is the workaround solution.
autopopulate is enabled globally, by following nestjs instruction :
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { SectionTemplate, SectionTemplateSchema } from './app.schema';
@Module({
imports: [
MongooseModule.forRoot('mongodb://localhost:27018/tbd', {
connectionFactory: (connection) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
connection.plugin(require('mongoose-autopopulate'));
return connection;
},
}),
MongooseModule.forFeature([
{ name: SectionTemplate.name, schema: SectionTemplateSchema },
]),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Nest throws following error when starting app :
[Nest] 4530 - 10/17/2022, 6:19:11 PM ERROR [ExceptionHandler] Maximum call stack size exceeded
RangeError: Maximum call stack size exceeded
at /home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:238:27
at Schema.eachPath (/home/foo/code/test-mongoose/node_modules/mongoose/lib/schema.js:1340:5)
at eachPathRecursive (/home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:238:10)
at /home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:241:7
at Schema.eachPath (/home/foo/code/test-mongoose/node_modules/mongoose/lib/schema.js:1340:5)
at eachPathRecursive (/home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:238:10)
at /home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:241:7
at Schema.eachPath (/home/foo/code/test-mongoose/node_modules/mongoose/lib/schema.js:1340:5)
at eachPathRecursive (/home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:238:10)
at /home/foo/code/test-mongoose/node_modules/mongoose-autopopulate/index.js:241:7
I also share this example's dependencies
{
"dependencies": {
"@nestjs/apollo": "^10.1.3",
"@nestjs/common": "^9.0.0",
"@nestjs/core": "^9.0.0",
"@nestjs/graphql": "^10.1.3",
"@nestjs/mongoose": "^9.2.0",
"@nestjs/platform-express": "^9.0.0",
"apollo-server-express": "^3.10.3",
"graphql": "^16.6.0",
"mongoose": "^6.6.5",
"mongoose-autopopulate": "^0.16.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.2.0"
},
"devDependencies": {
"@nestjs/cli": "^9.0.0",
"@nestjs/schematics": "^9.0.0",
"@nestjs/testing": "^9.0.0",
"@types/express": "^4.17.13",
"@types/jest": "28.1.8",
"@types/node": "^16.0.0",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "28.1.3",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "28.0.8",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.0",
"typescript": "^4.7.4"
},
}
Fixed here: https://github.com/mongodb-js/mongoose-autopopulate/pull/106