Home > Back-end >  Typescript Mongoose: Why are methods of aggregated documents undefined
Typescript Mongoose: Why are methods of aggregated documents undefined

Time:02-11

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>;
  • Related