我正在尝试使用Yup的.test()
方法在Formik中进行异步验证,并且需要设置从API获得的错误消息。错误消息会根据后端的某些情况而有所不同。
尝试了此处提到的几种解决方案
https://github.com/jquense/yup/issues/222和Dynamic Validation Messages Using Yup and Typescript
但是,Yup会抛出test()
中给出的默认错误消息。
文档说
所有测试必须提供名称,错误消息和必须返回true或false或ValidationError的验证函数。要使测试异步进行,请返回可解决true或false或ValidationError的Promise。
我正在使用错误消息解决新的ValidationError,但仍然会引发默认错误。
这是代码。
const schema = Yup.object().shape({
email: Yup.string().test(
"email_async_validation",
"Email Validation Error", // YUP always throws this error
value => {
return new Promise((resolve, reject) => {
emailValidationApi(value)
.then(res => {
const { message } = res.data; // I want this error message to be shown in form.
resolve(new Yup.ValidationError(message));
})
.catch(e => {
console.log(e);
});
});
}
)
});
答案 0 :(得分:1)
实际上,您几乎是正确的。您只需要使用以下内容:
resolve(this.createError({ message: message }));
让我知道它是否仍然无法正常工作
答案 1 :(得分:0)
不要传递第二个参数,因为我们通常将其作为错误消息传递,而是使用“ createError”创建您自己的自定义消息并根据您的条件返回它。
import * as yup from "yup";
const InitiateRefundSchema = yup.object().shape({
amountPaid: yup.number(),
refundAmount: yup
.number()
.test("test-compare a few values", function (value) {
let value1 = this.resolve(yup.ref("amountPaid"));
let value2 = this.resolve(yup.ref("refundAmount"));
if (value1 < value2) {
return this.createError({
message: `refund amount cannot be greater than paid amount '${value1}'`,
path: "refundAmount", // Fieldname
});
} else return true;
}),
})
答案 2 :(得分:0)
我使用function
语法而不是使用箭头函数作为验证功能。
医生说:
使用特殊上下文或this
值调用test函数, 展示一些有用的元数据和功能。请注意,要使用
this
在上下文中,测试函数必须是函数表达式(function test(value) {})
,而不是箭头函数,因为箭头函数具有 词汇语境。
这是工作代码。
const schema = Yup.object().shape({
email: Yup.string()
.email("Not a valid email")
.required("Required")
.test("email_async_validation", "Email Validation Error", function (value) { // Use function
return emailValidationApi(value)
.then((res) => {
const message = res;
console.log("API Response:", message);
return this.createError({ message: message });
// return Promise.resolve(this.createError({ message: message })); // This also works
})
.catch((e) => {
console.log(e);
});
})
});
答案 3 :(得分:0)
我也可以使用箭头函数来做到这一点。
const schema = Yup.object().shape({
email: Yup.string()
.email("Not a valid email")
.required("Required")
.test("email_async_validation", "Email Validation Error", (value, {createError}) {
return emailValidationApi(value)
.then((res) => {
const message = res;
console.log("API Response:", message);
return createError({ message: message });
})
.catch((e) => {
console.log(e);
});
})
});