'TS2339: Property 'comparePassword' does not exist on type 'Model<Document, {}>'
I have defined a schema method by using this code. While I use in the service. It is showing a error.
// model
export interface User extends mongoose.Document {
name: {
type: String,
required: [true, 'Please tell us your name.']
},
username: {
type: String,
required: [true, 'Please select a username.']
},
email: {
type: String,
required: [true, 'Please provide us your email.'],
lowercase: true,
unique: true,
validate: [validator.isEmail, 'Please provide us your email.']
},
password: {
type: String,
required: [true, 'Please select a password.'],
minLength: 8
select: false
},
passwordConfirmation: {
type: String,
required: [true, 'Please re-enter your password.'],
minLength: 8,
},
comparePassword(password: string): boolean
}
// method declared
userSchema.method('comparePassword', function (password: string): boolean {
if (bcrypt.compareSync(password, this.password)) {
return true;
} else {
return false;
}
});
// service file
public loginUser = async(req: Request, res: Response, next) => {
const {username, password} = req.body;
if(!username || !password){
res.status(400).json({
status: 'failed',
message: 'Please provide username and password.'
});
return next(new AppError('Please provide username and password.', 400));
} else {
const person = await [![User][1]][1].comparePassword(password);
const token = signToken(person._id);
res.status(200).json({
status: 'success',
accessToken : token
});
}
}
this line shows me the error.
const person = await User.comparePassword(password);
This is the screenshot in editor.
THis is the terminal screenshot
Can I know what is the problem here. I tried seeing the solution but could not find.
Solution 1:[1]
There was error in exporting the model.
export const User = mongoose.model<user>("User", userSchema);
And in the exporting interface add declare the function.
export interface user extends mongoose.Document {
name: String,
username: String,
email: String,
password: String,
passwordConfirmation: String,
comparePassword(candidatePassword: string): Promise<boolean>;
}
And the function is defined like this.
userSchema.methods.comparePassword = function (candidatePassword: string): Promise<boolean> {
let password = this.password;
return new Promise((resolve, reject) => {
bcrypt.compare(candidatePassword, password, (err, success) => {
if (err) return reject(err);
return resolve(success);
});
});
};
Then there was error in calling the function person.comparePassword()
. It should be called after finding the existing user. As @Mohammed Amir Ansari stated. the error was corrected and the actual error was exporting a model.
Solution 2:[2]
The Schema method you define will be available with mongoose instances i.e documents in your collection and not with the model. Also you are directly trying to compare the password which should not be the case. You should first check if the user exists or not and if the user found, you can call your comparePassword() using the user document, the code for the same will be:
public loginUser = async (req: Request, res: Response, next) => {
const {
username,
password
} = req.body;
if (!username || !password) {
res.status(400).json({
status: 'failed',
message: 'Please provide username and password.'
});
return next(new AppError('Please provide username and password.', 400));
} else {
const person = await User.findOne({
username
});
if (!person) {
return res.status(404).json({
message: 'No User Found.'
});
}
const isValidPassword = await person.comparePassword(password);
if (isValidPassword) {
const token = signToken(person._id);
return res.status(200).json({
status: 'success',
accessToken: token
});
} else {
return res.status(400).json({
status: 'fail',
message: 'Invalid Password!!'
});
}
}
}
Hope this helps :)
Solution 3:[3]
for my case
export interface IUserSchema extends Document {
firstName: string;
lastName: string;
username: string;
email: string;
password: string;
profilePic?: string;
comparePassword(candidatePassword: string): Promise<boolean>;
}
UserSchema.methods.comparePassword = async function (candidatePassword: string): Promise<boolean> {
const user = this as IUserSchema;
try {
return await bcrypt.compare(candidatePassword, user.password)
} catch (error) {
throw new Error("some thing wrrrong in the "+error)
}
};
how to used it
var result = await user.comparePassword(dto.password);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Prashanth Damam |
Solution 2 | Mohammed Amir Ansari |
Solution 3 | Mohammed Al-Reai |