How can I add instance/static methods to Mongoose schema when using @nestjs/mongoose? (TypeScript Issues) How can I add instance/static methods to Mongoose schema when using @nestjs/mongoose? (TypeScript Issues) mongoose mongoose

How can I add instance/static methods to Mongoose schema when using @nestjs/mongoose? (TypeScript Issues)


Here is what I managed to do:

export type UserDocument = User & Document;@Schema()export class User extends Document {  @Prop({ required: true, unique: true })  email!: string;  @Prop({ required: true })  passwordHash!: string;  toGraphql!: () => UserType;}export const UserSchema = SchemaFactory.createForClass(User);UserSchema.methods.toGraphql = function (this: User) {  const user = new UserType();  user.id = this._id;  user.email = this.email;  return user;};

Just added

toGraphql!: () => UserType;

to class


Actually you are calling method on model, you have to call the method on created document, or returned document by model.

Method on schema.

UserSchema.methods.comparePassword = async function(candidatePassword: string) {  return await bcrypt.compare(candidatePassword, this.password);};

Interface containing defined function.

export interface User {  comparePassword(candidatePassword: string): Promise<boolean>;}

In my case I had already been using UserDocument which had User & Document. I add it when injecting model.

constructor(    @InjectModel(User.name) private readonly userModel: Model<UserDocument, UserFunction>  ) {  }@Injectable()export class AuthService {  constructor(    private readonly usersService: UsersService,    private readonly jwtService: JwtService,) { }async signIn({ email, password }: SignInDto): Promise<LoginResponse> {const user = await this.usersService.findByEmail(email); // Document foundif (!user) { throw new UnauthorizedException('Invalid Username or Password'); }if (await user.comparePassword(password)) // <- Calling Schema method here {  const tokenPayload: JwtPayload = { userId: user.id };  const token = this.jwtService.sign(tokenPayload);  return ({ token, userId: user.id, status: LoginStatus.success });} else {  throw new UnauthorizedException('Invalid Username or Password');}

I had been calling the methods on userModel itself instead of calling it on it's document. Thanks to @Pantera answer I spotted the mistake.