问题描述
用户将作为一组对象发送联系信息,如下所示,电话号码是可选的,电子邮件是必需的:
{
"contact": [{
"type": "phone","value": "555-555-5555"
},{
"type": "email","value": "test@test.com"
}]
}
我想确保数组中有一个电子邮件对象。我尝试了这样的 Joi 验证:
contact: Joi.array().items(Joi.object().keys({
type: Joi.string().valid('phone','email'),value: Joi.string()
.when('contact.type',{ is: 'phone',then: Joi.string() })
.when('contact.type',{ is: 'email',then: Joi.string().email().required() })
}))
.when('contact.type',then: Joi.array().min(2).required() }),
但我收到以下错误:
Error: Item cannot come after itself: contact
它似乎不喜欢我以这种方式给它一个长度,但我想不出任何其他方法来做到这一点。任何帮助,将不胜感激。谢谢。
解决方法
这个结合了 .when、.has 和 .unique 的架构应该可以工作:
Joi.object({
contact: Joi.array().items(
Joi.object().keys({
type: Joi.string().valid('phone','email').required(),value: Joi.string().when('type',{ is: 'email',then: Joi.required() })
}).required(),)
.has(Joi.object({ type: 'email',value: Joi.exist() }))
.unique('type').min(1).max(2)
})
让我们看看规则:
- 必须存在类型为“email”的对象;
这就是我添加的原因
.has(Joi.object({ type: 'email',value: Joi.exist() }))
这意味着数组必须至少具有这些元素之一。
- 我们不想重复,对吧?
.unique('type').min(1).max(2)
数组将有 1 个或 2 个元素,具有不同的类型。
- 当类型为“email”时,该值应该是必需的,否则是可选的。这就是我们在这里所说的:
value: Joi.string().when('type',then: Joi.required() })
,
感谢@soltex 的回答。
首先,我不确定我们是否应该排除重复项。有些人有多个电话号码。
其次,您的回答不太奏效。这是我根据您写的内容更新的答案:
contact: Joi.array().items(Joi.object().keys({
type: Joi.string().valid('phone',value: Joi.string().required(),}))
.has(Joi.object({ type: 'email',value: Joi.string().email() }))
一旦我包含了 .has
方法,就没有理由包含 .when
方法。我还希望电子邮件是有效的电子邮件,而不仅仅是它存在。我将值更改为 required 因为如果用户发送类型电话我仍然希望他们包含该值。
再次感谢您的指导。