Hmm, despite having these options passed to Schema constructor:
toObject: { virtuals: true, getters: true },
toJSON: { virtuals: true, getters: true },
,my virtual field getter's return value doesn't seem to have any effect on caller.
userSchema
.virtual('ownedProducts', {
ref: COLLECTION_NAMES.Product,
localField: '_id',
foreignField: 'sellerOwner',
})
.get((value, virtual, doc) => {
const _ = doc.$$populatedVirtuals.ownedProducts.map(
({ _id, name }: { _id: any; name: any }) => ({ _id, name })
);
console.log('(virtual get) /value:', value, '/virtual:', virtual, '/doc.ownedProducts:', _);
return _;
});
userSchema.methods.toJSON = function (): TUserPublic {
const user: IUser = this.toObject();
console.log('(toJSON) user:', user);
if (!user.accountType?.roleName) {
throw new Error('User role was not successfully populated!');
}
const userToExpose: TUserPublic = {
login: user.login,
email: user.email,
observedProductsIDs: user.observedProductsIDs || [],
accountType: user.accountType.roleName,
};
if (userToExpose.accountType === USER_ROLES_MAP.seller) {
if (!user.ownedProducts) {
throw new Error('User ownedProducts not succesfully populated for seller role!');
}
console.log('(toJSON) /user.ownedProducts:', user.ownedProducts);
userToExpose.ownedProducts = user.ownedProducts;
}
return userToExpose;
};
Logs are on screenshot (getter correctly maps array to contain objects with only 2 props, but code inside .toJSON() doesn't seem to trigger/be affected by getters, because user.ownedProducts virtual field returns whole array instead of mapped one).
So, by unknown reason, user.ownedProducts returns array of "whole" objects, instead of mapped to objects with skipped props. (and there are no errors)