i'm currently making a server with javascript, koa, and mongoose. i made two different mongoose instance methods, which receives password from JSON body and hashes it with bcrypt, saves it on a 'hashedPassword' on user.
Initially, i wrote the second setPassword function (which uses promise, 'then' methods.), but when the user document saved, the 'hashedPassword' property didn't showed up.
so i tried with first one, it worked well and user document has saved with hashedPassword.
although these two instance methods looks similar, i wonder why these methods leads to different result.. please help
import mongoose from "mongoose";
import bcrypt from "bcrypt";
const UserSchema = mongoose.Schema({
username: String,
hashedPassword: String,
});
UserSchema.methods.setPassword = async function (password) {
const hash = await bcrypt.hash(password, 10);
this.hashedPassword = hash;
};
// UserSchema.methods.setPassword = async function (password) {
// bcrypt.hash(password, 10).then((hash) => {
// this.hashedPassword = hash;
// });
// };
// this code didn't save the hashed
const User = mongoose.model("user", UserSchema);
export default User;
user controller would be like this
const register = async (ctx) => {
const { username, password } = ctx.request.body;
try {
const user = new User({
username,
});
await user.setPassword(password);
await user.save();
catch(e) { ctx.throw(500,e) }
}
CodePudding user response:
This is not a mongoose-specific issue, you need to revise your understanding of how promises work.
Adding await
before bcrypt.hash
in the commented-out code should make it work, but there is no reason for you here to prefer .then
over await
.
In the second example, setPassword
only fires the hashing process and doesn't ask the caller to wait until the hashing is done, and then adds the hashed password to the document, while the first one does.
CodePudding user response:
You can try this approach using schema built-in methods:
UserSchema.pre('save', async function (next) {
if (this.isModified('hashedPassword')) {
this.hashedPassword= await bcrypt.hash(this.hashedPassword, 10)
}
next()
})
CodePudding user response:
Use this pre-save function inside the schema like that :
UserSchema.pre('save', async function (next) {
// Only if password was moddified
if (!this.isModified('hashedPassword')) return next();
// then Hash password
this.hashedPassword = await bcrypt.hash(this.hashedPassword, 10);
next();
});