Home > Back-end >  mongoose instance methods are showing different results
mongoose instance methods are showing different results

Time:09-27

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.

two documents using two different user instance methods

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();
});
  • Related