Search code examples
javascriptmongoosemethodsinstancekoa

mongoose instance methods are showing different results


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) }
    }

Solution

  • 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.