skip to Main Content

I am getting an error after trying to use the POST method through postman to register a user. I have created a simple Schema for the register route.

Error:

Error in register: Error: User validation failed: password: Cast to string failed for value "Promise { <pending> }" (type Promise) at path "password"
    at ValidationError.inspect (/Users/*****/authSystem/node_modules/mongoose/lib/error/validation.js:48:26)
    at formatValue (node:internal/util/inspect:782:19)
    at inspect (node:internal/util/inspect:347:10)
    at formatWithOptionsInternal (node:internal/util/inspect:2167:40)
    at formatWithOptions (node:internal/util/inspect:2029:10)
    at console.value (node:internal/console/constructor:324:14)
    at console.log (node:internal/console/constructor:360:61)
    at /Users/harshmishra/Desktop/BackendApp/authSystem/app.js:46:17
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {

  errors: {
    password: CastError: Cast to string failed for value "Promise { <pending> }" (type Promise) at path "password"
        at SchemaString.cast (/Users/*****/authSystem/node_modules/mongoose/lib/schema/string.js:600:11)
        at SchemaString.SchemaType.applySetters (/Users/*****/authSystem/node_modules/mongoose/lib/schematype.js:1189:12)
        at model.$set (/Users/***/authSystem/node_modules/mongoose/lib/document.js:1409:20)
        at model.$set (/Users/*****/authSystem/node_modules/mongoose/lib/document.js:1137:16)
        at model.Document (/Users/****/authSystem/node_modules/mongoose/lib/document.js:162:12)
        at model.Model (/Users/****/authSystem/node_modules/mongoose/lib/model.js:115:12)
        at new model (/Users/*****/authSystem/node_modules/mongoose/lib/model.js:4825:15)
        at /Users*****/authSystem/node_modules/mongoose/lib/model.js:3132:22
        at /Users/*****/authSystem/node_modules/mongoose/lib/model.js:3168:7
        at Array.forEach (<anonymous>) {
      stringValue: '"Promise { <pending> }"',
      messageFormat: undefined,
      kind: 'string',
      value: [Promise],
      path: 'password',
      reason: null,
      valueType: 'Promise'
    }
  },
  _message: 'User validation failed'
}

Schema:

const userSchema = new mongoose.Schema(
  {
    firstName: {
      type: String,
      default: null,
    },
    lastName: {
      type: String,
      default: null,
    },
    email: {
      type: String,
      unique: true,
    },
    password: {
      type: String,
    },
    token: {
      type: String,
    },
  },
);

module.exports = mongoose.model('User', userSchema)

/register:

app.post("/register", async(req, res) => {
    try {
        const { firstName, lastName, email, password } = req.body;
        if (!(firstName && lastName && email && password)) {
         return res.status(400).send("All fields are required");
        }
        const existingUser =User.findOne({ email });

        if (existingUser) {
          return res.status(401).send("User already exist");
        }
        const myEncrpytedPass = await bcryptjs.hash(password, 10);
        const user = await User.create({
          firstName,
          lastName,
          email: email.toLowerCase(),
          password: myEncrpytedPass,
        });
        const token = await jwt.sign(
          {
            user_id: user._id,
            email,
          },
          process.env.SECRET_KEY,
          {
            expiresIn: "4h",
          }
        );
        user.token = token;
      return res.status(201).json(user);
    } catch (error) {
        console.log("Error in register:",error)
   }
})

I am not able to figure out what I am doing wrong here? As I have followed the docs of a mongoose but still I am getting the error.

What changes should I make here?

2

Answers


  1. There are two things that you need to change:

    First

    Try adding await before the bcryptjs.hash(). Looks like that function returns a Promise.

    const myEncrpytedPass = await bcryptjs.hash(password, 10);
    

    Second

    Add return before each res.send.

    For example, if user exists, you will send this res.send(401).send("User already exist"), but because you didn’t add return, function will continue, and will reach to the next res.status(201).json(user) response. This will throw an error like Cannot set headers after they are sent to the client because you have already sent the response to the user.

    Login or Signup to reply.
  2. app.post("/register", async(req, res) => {
        try {
            const { firstName, lastName, email, password } = req.body;
            if (!(firstName && lastName && email && password)) {
              res.status(400).send("All fields are required");
            }
            const existingUser = await User.findOne({ email });
    
            if (existingUser) {
              res.send(401).send("User already exist");
            }
            const myEncrpytedPass = await bcryptjs.hash(password, 10);
            const user = await User.create({
              firstName,
              lastName,
              email: email.toLowerCase(),
              password: myEncrpytedPass,
            });
            const token = await jwt.sign(
              {
                user_id: user._id,
                email,
              },
              process.env.SECRET_KEY,
              {
                expiresIn: "4h",
              }
            );
            user.token = token;
            res.status(201).json(user);
        } catch (error) {
            console.log("Error in register:",error)
       }
    })
    

    You need to await jwt sign and bcrypt

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search