skip to Main Content

I am trying to validate a schema. its not very complex. below is my code

 Joi.object({
  mobile: Joi.string()
    .label('mobile')
    .pattern(/^(+)[1-9]d{7,14}$/)
    .messages({
      'string.pattern.base': 'Invalid mobile number',
    }),
  email: Joi.string()
    .email({ tlds: { allow: false } })
    .label('email')
    .messages({
      'string.email': 'Invalid email address',
    }),
  fullName: Joi.string()
    .label('fullName')
    .pattern(/^[A-Za-z]+[A-Za-zs]*$/)
    .max(100)
    .messages({
      'string.pattern.base': 'The fullName must be a valid string',
    }),
  firstName: Joi.string()
    .regex(/^[A-Za-zs]+$/i)
    .label('first name')
    .messages({
      'string.pattern.base': 'Only alphabets are allowed in first name.',
    }),
  middleName: Joi.string()
    .regex(/^[A-Za-zs]+$/i)
    .label('middle name')
    .messages({
      'string.pattern.base': 'Only alphabets are allowed in middle name.',
      'any.required': 'Middle name is required.',
    }),
  lastName: Joi.string()
    .regex(/^[A-Za-zs]+$/i)
    .label('last name')
    .messages({
      'string.pattern.base': 'Only alphabets are allowed in last name.',
      'any.required': 'Last name is required.',
    }),
}).or(
  'mobile', 
  'email'
).messages({
  'object.missing': 'Either mobile number or email is required',
}).or(
  'fullName', 
  'firstName'
).messages({
  'object.missing': 'Either full name or first name is required',
}).with(
  'firstName', 
  'lastName'
).messages({
  'object.with': 'If first name is provided, last name is required',
})

validation is working fine but problem is that when we dont provide email and mobile then the message says Either full name or first name is required instead of Either mobile number or email is required. how can i resolve it?

i have tried multiple placement even used Xor with it but no luck.

2

Answers


  1. Try this

    Joi.object({
      mobile: Joi.string()
        .label('mobile')
        .pattern(/^(+)[1-9]d{7,14}$/)
        .messages({
          'string.pattern.base': 'Invalid mobile number',
        }),
      email: Joi.string()
        .email({ tlds: { allow: false } })
        .label('email')
        .messages({
          'string.email': 'Invalid email address',
        }),
      fullName: Joi.string()
        .label('fullName')
        .pattern(/^[A-Za-z]+[A-Za-zs]*$/)
        .max(100)
        .messages({
          'string.pattern.base': 'The full name must be a valid string',
        }),
      firstName: Joi.string()
        .regex(/^[A-Za-zs]+$/i)
        .label('first name')
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in first name.',
        }),
      middleName: Joi.string()
        .regex(/^[A-Za-zs]+$/i)
        .label('middle name')
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in middle name.',
          'any.required': 'Middle name is required.',
        }),
      lastName: Joi.string()
        .regex(/^[A-Za-zs]+$/i)
        .label('last name')
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in last name.',
          'any.required': 'Last name is required.',
        }),
    })
    .or('mobile', 'email')
    .messages({
      'object.missing': 'Either mobile number or email is required',
    })
    .or('fullName', 'firstName')
    .messages({
      'object.missing': 'Either full name or first name is required',
    })
    .with('firstName', 'lastName')
    .messages({
      'object.with': 'If first name is provided, last name is required',
    });
    

    I guess the error shows because the .or() and .with() methods are being interpreted in an order that may not produce the expected error message.

    Login or Signup to reply.
  2. Try this

    Joi.object({
      mobile: Joi.string()
        .label('mobile')
        .pattern(/^(+)[1-9]d{7,14}$/)
        .messages({
          'string.pattern.base': 'Invalid mobile number',
        }),
      email: Joi.string()
        .email({ tlds: { allow: false } })
        .label('email')
        .messages({
          'string.email': 'Invalid email address',
        }),
      fullName: Joi.string()
        .label('fullName')
        .pattern(/^[A-Za-z]+[A-Za-zs]*$/)
        .max(100)
        .messages({
          'string.pattern.base': 'The fullName must be a valid string',
        }),
      firstName: Joi.string()
        .pattern(/^[A-Za-zs]+$/i)
        .label('first name')
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in first name.',
        }),
      middleName: Joi.string()
        .pattern(/^[A-Za-zs]+$/i)
        .label('middle name')
        .optional() // If middle name is optional, remove .required()
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in middle name.',
          'any.required': 'Middle name is required.',
        }),
      lastName: Joi.string()
        .pattern(/^[A-Za-zs]+$/i)
        .label('last name')
        .messages({
          'string.pattern.base': 'Only alphabets are allowed in last name.',
          'any.required': 'Last name is required.',
        }),
    })
    .or('mobile', 'email')
    .messages({
      'object.missing': 'Either mobile number or email is required',
    })
    .or('fullName', 'firstName')
    .messages({
      'object.missing': 'Either full name or first name is required',
    })
    .with('firstName', 'lastName')
    .messages({
      'object.with': 'If first name is provided, last name is required',
    });
    
    • Changed .regex() to .pattern() for consistency.
    • Ensured the .or() and .with() conditions are placed correctly at the end.
    • Explicitly marked middleName as optional if it’s not required. Remove .required() to make it optional.
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search