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)
}
CodePudding user response:
As per mongoose
docs,
The documents returned from aggregates are plain javascript objects, not mongoose documents (since any shape of document can be returned).
CodePudding user response:
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>;