我正在使用Joi验证复杂的表单条目。该表格要求两个地址mainContactAddress
和seniorContactAddress
。我想验证它们,以确保它们不是相同的地址。
每个地址都是这样的对象:
{
"line1": "123 Some Street",
"line2": "Some Town",
"county": "Some County",
"postcode": "123 ABC",
"townCity": "City"
}
我最初尝试过:
Joi.ukAddress().invalid(Joi.ref('seniorContactAddress'))
({ukAddress()
是我创建的自定义扩展名,它指定上述每个字段为必需的字符串。)
这不起作用,因为即使两个对象具有相同的字符串值,两个对象之间的相等性===
比较也会返回false
。
我看不到Joi方法可以做到这一点。我希望能够序列化对象(例如类似Object.values(mainContactAddress).join(',')
然后比较结果字符串),但是Joi.ref()
仅给出了对该对象的引用,所以我不能调用直接针对它起作用。
关于如何实现此验证/比较的任何想法吗?
答案 0 :(得分:0)
我最终为自己的扩展程序编写了一个自定义规则:
{
// Enforce a unique address compared to the senior contact
name: 'mainContact',
validate(params, value, state, options) {
// Format addresses into a comparable string,
// making sure we sort them as the stored version
// is in a different order to the form-submitted one.
const serialize = address =>
Object.values(address)
.sort()
.join(',');
const seniorContactAddress = get(
state.parent,
'seniorContactAddress',
[]
);
if (serialize(seniorContactAddress) === serialize(value)) {
return this.createError(
'address.matchesSenior',
{ v: value },
state,
options
);
} else {
return value;
}
}
}
这确实感觉像是一种反模式(例如,滥用state
来查看Joi对象中的其他值),但是它确实满足了我的需要。