skip to Main Content

I’m trying to perform user validation using if statements but on testing using post man, I keep on getting only the first return statement ‘Email is required ‘ even after adding a valid email address and also an invalid email address. I have attached the user model, user controller logic and a picture of postman’s response

user schema model

const mongoose = require('mongoose');
const { Schema } = mongoose

const userSchema = new Schema({
    firstName: {
        type: String,
        required: true,
        min: 3,
        max: 20
    },
    lastName: {
        type: String,
        required: true,
        min: 3,
        max: 20
    },
    email: {
        type: String,
        required: true,
        unique: true,
    },
    phoneNumber: {
        type: String,
        required: true,
    },
    password: {
        type: String,
        required: true,
        min: 5
    },
    confirmPassword: {
        type: String,
        required: true,
        min: 5
    }
});

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

module.exports = User;

user.controller.js

module.exports.users = async(req, res) => {
    try {
        const email = await user.findOne({ email: req.body.email });
        const firstName = await user.find({ firstName: req.body.firstName });
        const lastName = await user.find({ lastName: req.body.lastName });
        const password = await user.find({ password: req.body.password });
        const confirmPassword = await user.find({ confirmPassword: req.body.confirmPassword });
        const phoneNumber = await user.find({ phoneNumber: req.body.phoneNumber });

        if (!email) return res.send('Email is required')

        const filterEmail = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
        if (!filterEmail.test(email.value)) return
        res.send('Please provide a valid email address');
        if (email) return res.send('Email already exists');

        if (!firstName) return res.send('First Name is required');
        if (firstName.length < 3 || firstName.length > 20) return
        res.send('First name must be at least 3 characters and less than 20 characters');;

        if (!lastName) return res.send('Last Name is required');
        if (lastName.length < 3 || lastName.length > 20) return
        res.send('Last name must be at least 3 characters and less than 20 characters')

        if (!password) return res.send('PassWord is required');
        const filterPassword = /^(?=.*d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*s).{5,15}$/;
        if (!filterPassword.test(password.value)) return
        res.send('Password must include at least one lowercase letter, one uppercase letter, one digit, and one special character');
        if (!confirmPassword) return res.send(' Please confirm password');
        if (password.value !== confirmPassword.value) return res.send('Passwords do not match');

        if (!phoneNumber) return res.send('Phone Number is required');
        phone(phoneNumber.value);

        let User = new user(_.pick(req.body, ['firstName', 'lastName', 'email', 'phoneNumber', 'password']));

        bcrypt.genSalt(10, async(err, salt) => {
            if (err) throw err;
            return user.password = await bcrypt.hash(user.password, salt);
        });
        await User.save();


    } catch (err) {
        res.status(500).send('Something went wrong');
        console.warn(err);
    }
}

postMan response

4

Answers


  1. Your controller is not good. You need to get the email, lastName and firstName from req.body.

    
       const {email, lastName} = req.body
    
    

    And then do the validation, which by the way will already happen in mongoose.

    
        const email = await user.findOne({ email: req.body.email });
    
    

    In this line you are looking in your DB for a user with email = req.body.email. But since there is no such a user it return your if statement

    
       if (!email) return res.send('Email is required')
    
    

    to get your user you only need to compare with one value if you set it to be unique in your schema, for instead user email.

    const user = await user.findOne({ email });
    

    In this case email was already destructed and if there is no user, you can create one.

    you can use await user.create() and pass your values and hash the password with pre("save") in your schema.

    
        UserSchema.pre("save", async function () {
      if (!this.isModified("password")) return;
      const salt = await bcrypt.genSalt(10);
      this.password = await bcrypt.hash(this.password, salt);
    });
    
    

    You can also validate user email in the schema

    
            email: {
          type: String,
          required: [true, "Please provide email"],
          match: [
            /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/,
            "Please provide a valid email",
          ],
          unique: true,
        },
    
    
    Login or Signup to reply.
  2. You can simply install the validator package npm i validator then call it in in the user model const { isEmail } = require('validator'); and finally type this in your schema instead of hardcoding the verification code in the function.

    email: { type: String, required: true, validate: [isEmail], unique: true },
    
    Login or Signup to reply.
  3. Instead of writing custom logic for validation Please add a validation layer after performing security checks

    you can use Express validator, to perform all your validations in a smoother way, It will eliminate unnecessary logic and code lines and add structured code to validate all types inputs, nested objects, DB call for existing data handling. It will handle the response and response message on its own without hitting the controller

    just hit

    npm install --save express-validator

    and you are ready to validate requests very easily and effectively

    Login or Signup to reply.
  4. Beside other answers i thought one thing which is missing but yet it is very strong validation method in Node.JS is JOI package, you can define your validation schema and get rid of all other pain full if and else, example is following

    const Joi = require('joi'); 
    const schema = Joi.object().keys({ 
      firstName: Joi.string().alphanum().min(3).max(20).required(),
      lastName: Joi.string().alphanum().min(3).max(20).required(),
      email: Joi.email().required(),
      phoneNumber: Joi.string().length(10).pattern(/^[0-9]+$/).required(),
      password: Joi.string().min(5).required(),
      confirmPassword: Joi.any().valid(Joi.ref('password')).required()
    }); 
    const dataToValidate = { 
      firstName: 'chris', 
      lastName: 'John',
      email: '[email protected]' 
    } 
    const result = Joi.validate(dataToValidate, schema); 
    // result.error == null means valid
    

    Without node script you can always test your JOI schema and your data object on this webpage

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