Skip to content

Commit 5232984

Browse files
Merge pull request #2438 from schw4rzlicht/fix/populate
fix: populate on arrays
2 parents 2147221 + 684b9c6 commit 5232984

File tree

11 files changed

+118
-5
lines changed

11 files changed

+118
-5
lines changed

lib/factories/definitions.factory.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ export class DefinitionsFactory {
8585
return schemaDefinition;
8686
} else if (
8787
typeof optionsOrType.type === 'function' ||
88-
Array.isArray(optionsOrType.type)
88+
(Array.isArray(optionsOrType.type) &&
89+
typeof optionsOrType.type[0] === 'function')
8990
) {
9091
optionsOrType.type = this.inspectTypeDefinition(optionsOrType.type);
9192
return optionsOrType;

tests/e2e/mongoose.spec.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { Test } from '@nestjs/testing';
33
import { Server } from 'http';
44
import * as request from 'supertest';
55
import { AppModule } from '../src/app.module';
6+
import { CreateCatDto } from '../src/cats/dto/create-cat.dto';
7+
import { Cat } from '../src/cats/schemas/cat.schema';
68

79
describe('Mongoose', () => {
810
let server: Server;
@@ -32,6 +34,61 @@ describe('Mongoose', () => {
3234
});
3335
});
3436

37+
it('should populate array of kittens', async () => {
38+
let createDto: CreateCatDto = {
39+
name: 'Kitten',
40+
breed: 'Maine coon',
41+
age: 1,
42+
};
43+
44+
const kitten: Cat = await new Promise((resolve) => {
45+
request(server)
46+
.post('/cats')
47+
.send(createDto)
48+
.expect(201)
49+
.end((err, { body }) => {
50+
expect(body.name).toEqual(createDto.name);
51+
expect(body.age).toEqual(createDto.age);
52+
expect(body.breed).toEqual(createDto.breed);
53+
resolve(body);
54+
});
55+
});
56+
57+
createDto = {
58+
...createDto,
59+
name: 'Nest',
60+
age: 5,
61+
kitten: [kitten._id as string],
62+
};
63+
64+
const parent = await new Promise<string>((resolve) => {
65+
request(server)
66+
.post('/cats')
67+
.send(createDto)
68+
.expect(201)
69+
.end((err, { body }) => {
70+
expect(body.name).toEqual(createDto.name);
71+
expect(body.age).toEqual(createDto.age);
72+
expect(body.breed).toEqual(createDto.breed);
73+
resolve(body._id as string);
74+
});
75+
});
76+
77+
await new Promise<void>((resolve) => {
78+
request(server)
79+
.get(`/cat/${parent}`)
80+
.expect(200)
81+
.end((err, { body }) => {
82+
expect(Array.isArray(body.kitten)).toBe(true);
83+
expect(body.kitten[0]._id).toBe(kitten._id);
84+
expect(body.kitten[0].name).toBe(kitten.name);
85+
expect(body.kitten[0].breed).toBe(kitten.breed);
86+
expect(body.kitten[0].age).toBe(kitten.age);
87+
resolve();
88+
});
89+
});
90+
});
91+
3592
afterEach(async () => {
3693
await app.close();
3794
});

tests/e2e/schema.factory.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class ExampleClass {
2828
@Prop()
2929
array: Array<any>;
3030

31+
// see https://github.com/nestjs/mongoose/issues/839
32+
@Prop({ type: [ChildClass], required: true })
33+
anotherArray: ChildClass[];
34+
3135
@Virtual({
3236
options: {
3337
localField: 'array',

tests/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { Module } from '@nestjs/common';
22
import { MongooseModule } from '../../lib';
33
import { CatsModule } from './cats/cats.module';
4+
import { CatModule } from './cats/cat.module';
45

56
@Module({
67
imports: [
78
MongooseModule.forRoot('mongodb://localhost:27017/test'),
89
CatsModule,
10+
CatModule,
911
],
1012
})
1113
export class AppModule {}

tests/src/cats/cat.controller.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Controller, Get, Param } from '@nestjs/common';
2+
import { CatService } from './cat.service';
3+
import { Cat } from './schemas/cat.schema';
4+
5+
@Controller('cat')
6+
export class CatController {
7+
constructor(private readonly catService: CatService) {}
8+
9+
@Get(':id')
10+
async findOne(@Param('id') id: string): Promise<Cat | null> {
11+
return this.catService.findOne(id);
12+
}
13+
}

tests/src/cats/cat.module.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Module } from '@nestjs/common';
2+
import { MongooseModule } from '../../../lib';
3+
import { Cat, CatSchema } from './schemas/cat.schema';
4+
import { CatController } from './cat.controller';
5+
import { CatService } from './cat.service';
6+
7+
@Module({
8+
imports: [MongooseModule.forFeature([{ name: Cat.name, schema: CatSchema }])],
9+
controllers: [CatController],
10+
providers: [CatService],
11+
})
12+
export class CatModule {}

tests/src/cats/cat.service.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Injectable } from '@nestjs/common';
2+
import { Model } from 'mongoose';
3+
import { InjectModel } from '../../../lib';
4+
import { Cat } from './schemas/cat.schema';
5+
6+
@Injectable()
7+
export class CatService {
8+
constructor(@InjectModel(Cat.name) private readonly catModel: Model<Cat>) {}
9+
10+
async findOne(id: string): Promise<Cat | null> {
11+
return this.catModel.findById(id).populate('kitten').exec();
12+
}
13+
}

tests/src/cats/cats.service.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Injectable } from '@nestjs/common';
2-
import { Model } from 'mongoose';
2+
import { Model, Types } from 'mongoose';
33
import { InjectModel } from '../../../lib';
44
import { CreateCatDto } from './dto/create-cat.dto';
55
import { Cat } from './schemas/cat.schema';
@@ -9,7 +9,10 @@ export class CatsService {
99
constructor(@InjectModel(Cat.name) private readonly catModel: Model<Cat>) {}
1010

1111
async create(createCatDto: CreateCatDto): Promise<Cat> {
12-
const createdCat = new this.catModel(createCatDto);
12+
const createdCat = new this.catModel({
13+
...createCatDto,
14+
kitten: createCatDto.kitten?.map((kitten) => new Types.ObjectId(kitten)),
15+
});
1316
return createdCat.save();
1417
}
1518

tests/src/cats/dto/create-cat.dto.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ export class CreateCatDto {
22
readonly name: string;
33
readonly age: number;
44
readonly breed: string;
5+
readonly kitten?: string[];
56
}

tests/src/cats/schemas/cat.schema.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Document } from 'mongoose';
1+
import { Document, Types } from 'mongoose';
22
import { Prop, Schema, SchemaFactory } from '../../../../lib';
33

44
@Schema()
@@ -11,6 +11,13 @@ export class Cat extends Document {
1111

1212
@Prop()
1313
breed: string;
14+
15+
// see https://github.com/nestjs/mongoose/issues/2421
16+
@Prop({
17+
type: [{ type: Types.ObjectId, ref: Cat.name }],
18+
default: [],
19+
})
20+
kitten: Types.ObjectId[];
1421
}
1522

1623
export const CatSchema = SchemaFactory.createForClass(Cat);

0 commit comments

Comments
 (0)