Reputation: 121
I am currently working on a project where virtual populates are quite necessary:
There's a customer scheme, a document scheme as well as some others referencing the customer. Inside the customer I want to populate the referenced items.
I already had a working Model using Typegoose, which I had to remove from the project because of late incompatibilities. This is how it worked before:
@prop({
ref: () => DMSDocument,
foreignField: 'linkedCustomers', // compare this value to the local document populate is called on
localField: '_id', // compare this to the foreign document's value defined in "foreignField",
justOne: false
})
public documents: { type: Types.ObjectId, ref: 'DMSDocument' }[];
Now I was trying to achieve this using nestjs/mongoose only after removing typegoose:
@Prop({
virtual: 'documents',
ref: 'DMSDocument',
foreignField: 'linkedCustomers',
localField: '_id',
})
public documents: DMSDocument[];
Virtual getters working just fine since I'm just using
@Schema({ toJSON: { virtuals: true, getters: true }, toObject: { virtuals: true, getters: true }})
The model ist populated like this:
this.customerModel.findOne(params)
.populate('documents', '', 'DMSDocument')
.populate('repairs', '', 'Repair')
I am somehow stuck - I just get empty arrays, no errors. What Am I missing? Are they even possible using nestjs/mongoose?
Upvotes: 5
Views: 4769
Reputation: 455
Answer for 2024
You can achieve this in Nest.js now (my version is: 10.0.0) by doing the following:
In your customer module:
imports: [
MongooseModule.forFeatureAsync([{
name: Customer.name,
useFactory: () => {
const schema = CustomerSchema;
schema.virtual('documents', {
ref: 'DMSDocument',
localField: '_id',
foreignField: 'links.customers',
justOne: false
});
return schema;
}
}])
],
This is the link to the documentation: https://docs.nestjs.com/techniques/mongodb#hooks-middleware
You can also create virtuals directly in the schema like the following:
class Person {
@Prop()
firstName: string;
@Prop()
lastName: string;
@Virtual({
get: function (this: Person) {
return `${this.firstName} ${this.lastName}`;
},
})
fullName: string;
}
This is from the docs also. link: https://docs.nestjs.com/techniques/mongodb#virtuals
Upvotes: 0
Reputation: 121
Okay, I managed to get things working again, but not in a preferred way:
After defining the class and converting it to a schema via
export const CustomerSchema = SchemaFactory.createForClass(Customer);
I just had to "manually" add the virtual populates:
CustomerSchema.virtual('documents', {
ref: 'DMSDocument',
localField: '_id',
foreignField: 'links.customers',
justOne: false
});
Everything is working as expected, but I'd prefer a way using the decorators.
Upvotes: 3