简体   繁体   中英

How to require an object based on the value of an array using Joi validation

I am setting up validation for my api and need to require a phone number to be present if the notification the client would like to get is set to sms. The notification is set in the validation schema. I have the following code here that will illustrate this better, please note the .required().when() section. This makes the phone number field required every time, no matter what the notification_type array contains.

{
    body: {
        notification_type: Joi.array().unique().items(Joi.string().lowercase().valid(['sms', 'email')).min(1).max(3).optional(),
        customer: Joi.object().keys({
            first_name: Joi.string().required(),
            last_name: Joi.string().required(),
            email_address: Joi.string().email().required(),
            phone_number: Joi.string(), // make this required if notification_type contains 'sms'
            meta_data: Joi.object().optional()
        }).required().when('notification_type', {
            is: Joi.array().items(Joi.string().valid('sms')),
            then: Joi.object({ phone_number: Joi.required() })
        })
    }
}

What about:

phone_number: body.notification_type === 'sms' ? Joi.string().required() : Joi.string()

?

I think you want the phone number to be optional if the notification type array doesn't include sms and required if it does, you can define something like this:

const schema = Joi.object({
    notification_type: Joi.array().items(
        Joi.string().valid('email', 'sms')
    ),
    customer: Joi.object({
        phone_number: Joi.string(),
    })
}).when(Joi.object({
    notification_type: Joi.array().items(
        Joi.string().valid('sms').required(),
        Joi.string().valid('email').optional()
    )
}).unknown(), {
    then: Joi.object({
        customer: Joi.object({
            phone_number: Joi.string().required()
        }).required()
    }),
    otherwise: Joi.object({
        customer: Joi.object({
            phone_number: Joi.optional()
        })
    })
});

So, the following object will be accepted:

{
   notification_type:[
      'sms',
      'email'
   ],
   customer:{
      phone_number:'111-222-333'
   }
}

and this won't:

{
   notification_type:[
      'sms'
   ],
   customer:{

   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM