Let's say I have the following schemas:
parent.ts
export const ParentSchema = new Schema<IParent>(
{
children: {
type: [
{
type: Schema.Types.ObjectId,
ref: 'Child',
},
],
default: [],
},
},
{ timestamps: true }
);
export default model('Parent', ParentSchema, 'Parent');
child.ts
import Parent from './parent';
const ChildSchema = new Schema<IChild>(
{
parent: {
type: Schema.Types.ObjectId,
ref: 'Parent',
required: true,
},
},
{ timestamps: true }
);
ChildSchema.post('save', async function () {
const { _id, parent: parentId } = this;
console.log('pre findByIdAndUpdate');
await Parent.findByIdAndUpdate(parentId, { $push: { children: _id } });
console.log('post findByIdAndUpdate');
});
export default model('Child', ChildSchema, 'Child');
The Parent schema is actually a wrapper of multiple children, so it only makes sense to have a Parent if one Child is being created as well. So, I have this function:
parent-service.ts
async store() {
const newParent = await new Parent().save();
const newChild = await new Child({ parent: newParent._id }).save();
await newParent.populate('children');
// console.log(await Parent.findById(newParent._id));
return newParent;
}
I would expect that the returned object would be something like:
{
"_id": "1234567890abcdef",
"children": [
{
"_id": "fedcba0987654321",
"parent": "1234567890abcdef"
}
]
}
However, this is what is being returned by calling await store():
{
"_id": "1234567890abcdef",
"children": []
}
The console.log on post middleware at child.ts are printed, and if I remove the console.log commented out at parent-service.ts, it shows that indeed the middleware worked as intended and the id was added to the array of children.
Is this behavior expected, is it a bug?
What I've tried:
- Using
SchemaTypes.ObjectIdinstead ofSchema.Types.ObjectId; - Using
updateOneinstead offindByIdAndUpdateon the middleware;
I'm currently using, as a workaround, a spread on newParent putting children: [newChild], but I'd like to populate actually get the updated version of my document.
Thanks in advance.