Shoubhik Raj
Shoubhik Raj

Reputation: 151

Getting "ReferenceError: user is not defined" even user is defined

I'm working with routes on node js. I created a user model shown below -

const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const validator = require("validator");
require("dotenv").config();

const userSchema = mongoose.Schema(
  {
    email: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      lowercase: true,
      validate(value) {
        if (!validator.isEmail) {
          throw new Error("Invalid Email");
        }
      },
    },
    password: {
      type: String,
      required: true,
      trim: true,
    },
    role: {
      type: String,
      enum: ["user", "admin"],
      default: "user",
    },
    name: {
      type: String,
      required: true,
      maxlength: 21,
    },
    phone: {
      required: true,
      type: Number,
      maxlength: 12,
    },
  },
  { timestamps: true },
);

userSchema.pre("save", async function (next) {
  if (user.isModified("password")) {
    // hash the password
    const salt = await bcrypt.genSalt(10);
    const hash = await bcrypt.hash(this.password, salt);
    this.password = hash;
  }
  next();
});

const User = mongoose.model("User", userSchema);

module.exports = {
  User,
};

And then I created a file containing user routes shown below -

const express = require("express");
const router = express.Router();
require("dotenv").config();
const { User } = require("../../models/userModel");

router.route("/signup").post(async (req, res) => {
  //   const { email, password, name, phone } = req.body;
  console.log(req.body);

  //   try {
  //     // Check if user email exists

  //     // create user instance and hash password
  //     const user = new User({
  //       email: req.body.email,
  //       password: req.body.password,
  //       name: req.body.name,
  //       phone: req.body.phone,
  //     });

  //     // generate jwt token
  //     console.log("user is saving");
  //     const userDoc = await user.save();

  //     // send email

  //     // save....send token with cookie
  //     res
  //       .cookie("access-token", "jflsakjusdilfjadslfj32j43lrf")
  //       .status(200)
  //       .send(userDoc);
  //   } catch (error) {
  //     res
  //       .status(400)
  //       .json({ message: "Error while creating user", error: error });
  //   }

  const user = new User({
    name: req.body.name,
    email: req.body.email,
    password: req.body.password,
    phone: req.body.phone,
  });
  user
    .save()
    .then((doc) => {
      console.log("User saved");
      res.send(doc);
    })
    .catch((err) => {
      console.log(err);
    });
});

module.exports = router;

But don't know why I'm getting this error -

ReferenceError: user is not defined
    at model.<anonymous> (D:\CovidHelpers\CovidHelpers\server\models\userModel.js:46:3)
    at callMiddlewareFunction (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:483:23)
    at model.next (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:58:7)
    at _next (D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:107:10)
    at D:\CovidHelpers\CovidHelpers\node_modules\kareem\index.js:508:38
    at processTicksAndRejections (internal/process/task_queues.js:75:11)

I have just created a new project in mongodb, gave database and network access and it's connecting successfully but also getting this error

I have done this before also and it was working fine but don't know why am I getting this now :( Any help is appreciated

Upvotes: 0

Views: 2219

Answers (3)

NeNaD
NeNaD

Reputation: 20304

You can delete userSchema.pre() middleware and transfer the password hashing logic inside the router. Also you can simplify your router code like this:

router.route("/signup").post(async (req, res) => {
  try {
    const salt = await bcrypt.genSalt(10);
    const hash = await bcrypt.hash(req.body.password, salt);
    req.body.password = hash;
    let user = await User.create(req.body)
    res.status(200).json(user)
  } catch (error) {
    res.status(400).json({ error: error });
  }
});

RECOMMENDATION:

I would recommend you to try the great Mongoose plugin called passport-local-mongoose that will do this for you out of the box, and it will also give you some nice authentication features if you are using passport for authentication.

Package: https://www.npmjs.com/package/passport-local-mongoose

Upvotes: 1

Cuong Le Ngoc
Cuong Le Ngoc

Reputation: 11975

save is document middleware and in document middleware functions, this refers to the document. So in your case, I believe it should be this.isModified("password") instead of user.isModified("password").

Upvotes: 2

vighnesh153
vighnesh153

Reputation: 5388

You don't actually get access to the document, in the mongoose's pre('save') hook.

For your usecase, you can do the hasing before you save the user.

Upvotes: 0

Related Questions