When using mongoose aggregate it returns an array of ProfileDocuments. The Documents in the result array do not contain the methods of the ProfileDocument implementation. Which leads to being unable to call document methods like checkPassword on the documents from the database.
Aggregate Example
ProfileSchema.statics.findByLogin = async function (login: string) {
// why do methods of aggregated documents not work?
const results = await this.aggregate([{
$match: {
$or:[{username: login}, {mail: login}]
}
}])
if (results.length === 0) {
throw new Error('Profile not found')
}
const profile = await this.findById(results[0]._id)
console.log(results[0].checkPassword)
console.log(profile.checkPassword)
return profile
}
Console Output
undefined
[Function (anonymous)]
Method implementation
interface ProfileDocument extends IProfile, Document {
getDisplayname: () => Promise<string>
}
ProfileSchema.methods.checkPassword = async function (password: string) {
return await bcrypt.compare(password, this.pass)
}
As @Thakur mentioned aggregate returns raw documents. Mongoose offers a hydrate method to add the methods to a document.
Use ProfileSchema.hydrate(doc)
or in the context of the static method this.hydrate(doc)
returns ProfileDocuments.
/**
* Shortcut for creating a new Document from existing raw data, pre-saved in the DB.
* The document returned has no paths marked as modified initially.
*/
hydrate(obj: any): EnforceDocument<T, TMethods>;