node.js - TS2339: Proprietatea 'comparePassword' nu există pe tipul 'Model'
Am definit o metodă de schemă folosind acest cod. Când o folosesc în serviciu, apare o eroare.
// 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
}
// metodă declarată
userSchema.method('comparePassword', function (password: string): boolean {
if (bcrypt.compareSync(password, this.password)) {
return true;
} else {
return false;
}
});
// fișier de serviciu
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
});
}
}
această linie îmi arată eroarea.
const person = await User.comparePassword(password);Aceasta este captura de ecran în editor.
Aceasta este captura de ecran a terminalului
Pot să știu care este problema aici. Am încercat să văd soluția, dar nu am putut să o găsesc.
Răspuns #1
A apărut o eroare la exportarea modelului.
export const User = mongoose.model<user>("User", userSchema);
Și în interfața de export adaugă declararea funcției.
export interface user extends mongoose.Document {
name: String,
username: String,
email: String,
password: String,
passwordConfirmation: String,
comparePassword(candidatePassword: string): Promise<boolean>;
}
Și funcția este definită astfel.
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);
});
});
};
Apoi a existat o eroare la apelarea funcției person.comparePassword(). Aceasta ar trebui apelată după ce se găsește utilizatorul existent. Așa cum a afirmat @Mohammed Amir Ansari, eroarea a fost corectată, iar eroarea reală a fost exportarea unui model.
Răspunsul #2
Metoda Schema pe care o definești va fi disponibilă cu instanțele mongoose, adică documentele din colecția ta, și nu cu modelul. De asemenea, încerci direct să compari parola, ceea ce nu ar trebui să fie cazul. Ar trebui mai întâi să verifici dacă utilizatorul există sau nu și, dacă utilizatorul este găsit, poți apela comparePassword() folosind documentul utilizatorului, codul pentru aceasta va fi:
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!!'
});
}
}
}
Sper că asta ajută :)

