Home > OS >  how to solve a 'res is not defined' error in nodejs
how to solve a 'res is not defined' error in nodejs

Time:09-12

I am trying to get test the controller logic for a user validation module but I keep on landing res is not defined error even after trying to define it. How I'm I supposed properly define it so that it is able to correctly run through the condition statements correctly?

my common.js validation logic

const user = require('../models/user');

module.exports = {
    verifyEmail: async(email) => {
        if (!email) {
            return res.status(404).json({ message: 'Email is required' })
        }
        let regex = /^\w ([\.-]?\w )*@\w ([\.-]?\w )*(\.\w{2,3}) $/;
        if (!email.match(regex)) {
            return res.status(400).json({ message :'invalid email address' })
        }
        let User = await user.findOne({ email });
        if (User) {
            return res.status(400).json({ message: 'User already exists' })
        }

    },
    verifyFirstName: (firstName) => {
        if (!firstName) {
            return res.status(404).json({ message: 'First name is required' });
        }
        if (firstName.length < 3 || firstName.length > 20) {
            return res.status(411).json({ message: 'length must be between 3 and 20 characters' });
        }
    },
    verifyLastName: (lastName) => {
        if (!lastName) {
            return res.status(404).json({ message: 'First name is required' });
        }
        if (lastName.length < 3 || lastName.length > 20) {
            return res.status(411).json({ message: 'length must be between 3 and 20 characters' });
        }
    },
    verifyPassword: (password, confirmPassword) => {
        if (!password) {
            return res.status(404).json({ message: 'Password field is required' })
        }
        if (password.length < 5) {
            return res.status(411).json({ message: 'Password is too short' })
        }
        let passRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{5,15}$/;
        if (!password.match(passRegex)) {
            return res.status(400).json({ message: 'Password must include at least one lowercase letter, one uppercase letter, one digit, and one special character' });
        }
        if (password !== confirmPassword) {
            return res.status(417).json({ message: 'passwords do not match' })
        }
    },
    verifyPhone: (phoneNumber) => {
        if (!phoneNumber) {
            return res.status(404).json({ message: 'Phone number is required' })
        }
        let phoneRegex = /^\ ?\d{1,4}?[-.\s]?\(?\d{1,3}?\)?[-.\s]?\d{1,4}[-.\s]?\d{1,4}[-.\s]?\d{1,9}$/
        if (!phoneNumber.match(phoneRegex)) {
            return res.status(400).json({ message: 'Please add a valid phone number' })
        }
    }

}

controller.js

module.exports.users = async(req, res) => {
    try {
        const { email, firstName, lastName, password, confirmPassword, phoneNumber } = req.body

        verifier.verifyEmail(email);
        verifier.verifyFirstName(firstName);
        verifier.verifyLastName(lastName);
        verifier.verifyPassword(password, confirmPassword);
        verifier.phoneNumber(phoneNumber);


        let User = new user({
            firstName: req.body.firstName,
            lastName: req.body.lastName,
            password: req.body.password,
            phone: req.body.phoneNumber

        })

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

CodePudding user response:

res doesn't seem to be defined in your validation logic. You can try returning the status and message to your controller instead.

e.g.

    verifyEmail: async(email) => {
        if (!email) {
            return { status: 404, message: 'Email is required' };
        }
        ...
    },

then in your controller,

let emailValidation = verifier.verifyEmail(email);
if (emailValidation.status === 404 || emailValidation.status === 400) {
    res.status(emailValidation.status).json({ message: emailValidation.message });
}

CodePudding user response:

Rather than using custom validation, I will recommend you use the Joi package for validation. So your end file will look like this.

Joi Package

validation.js

const Joi = require('joi')

const validateSchema = (body, schema) => {
  try {
    const { error } = schema.validate(body)
    return { error }
  } catch (err) {
    throw err
  }
}

exports.userValidator = (body) => {
  const schema = Joi.object({
    email: Joi.string().email({ minDomainSegments: 2 }).required(),
    firstName: Joi.string().min(3).max(20),
    lastName: Joi.string().min(3).max(20),
    password: Joi.string().required(),
    phoneNumber: Joi.string()
      .length(10)
      .pattern(/^[0-9] $/)
      .required()
  })

  return validateSchema(body, schema)
}

controller.js

 module.exports.user = async (req, res, next) => {
  try {
    // const { email, firstName, lastName, password, phoneNumber } = req.body

    const { error } = userValidator(req.body)
    if (error) return res.status(400).json({ message: 'Error occured!', error })

    let user = await User.findOne({ email: req.body.email })
    if (user) {
      return res.status(400).json({ message: 'User already exists' })
    }

    bcrypt.genSalt(10, async (err, salt) => {
      if (err) throw err
      req.body.password = await bcrypt.hash(user.password, salt)
    })

    user = new User(req.body)

    await user.save()
  } catch (err) {
    console.log(err)
  }
}
  • Related