如何在 Yup 异步验证中设置动态错误消息?
How to set dynamic error messages in Yup async validation?
我正在尝试使用 Yup 的 .test()
方法在 Formik 中进行异步验证,并且需要设置我从 API 获得的错误消息。错误消息将根据后端的某些条件而有所不同。
尝试了这里提到的几个解决方案
https://github.com/jquense/yup/issues/222 and Dynamic Validation Messages Using Yup and Typescript
但是 Yup 正在抛出 test()
中给出的默认错误消息。
文档说
All tests must provide a name, an error message and a validation function that must return true or false or a ValidationError. To make a test async return a promise that resolves true or false or a ValidationError.
我正在用错误消息解决一个新的 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);
});
});
}
)
});
其实你差不多correct.You只需要使用以下内容:
resolve(this.createError({ message: message }));
如果还是不行,请告诉我
不要传递第二个参数,因为我们通常将其作为错误消息传递,而不是使用“createError”创建您自己的自定义消息,return 根据您的情况。
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;
}),
})
我使用 function
语法而不是箭头函数来验证函数。
文档说:
test functions are called with a special context, or this
value, that
exposes some useful metadata and functions. Note that to use this
context, the test function must be a function expression (function test(value) {})
, not an arrow function, since arrow functions have
lexical context.
这是工作代码。
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);
});
})
});
我也可以用箭头函数来做到这一点。
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);
});
})
});
我正在尝试使用 Yup 的 .test()
方法在 Formik 中进行异步验证,并且需要设置我从 API 获得的错误消息。错误消息将根据后端的某些条件而有所不同。
尝试了这里提到的几个解决方案
https://github.com/jquense/yup/issues/222 and Dynamic Validation Messages Using Yup and Typescript
但是 Yup 正在抛出 test()
中给出的默认错误消息。
文档说
All tests must provide a name, an error message and a validation function that must return true or false or a ValidationError. To make a test async return a promise that resolves true or false or a ValidationError.
我正在用错误消息解决一个新的 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);
});
});
}
)
});
其实你差不多correct.You只需要使用以下内容:
resolve(this.createError({ message: message }));
如果还是不行,请告诉我
不要传递第二个参数,因为我们通常将其作为错误消息传递,而不是使用“createError”创建您自己的自定义消息,return 根据您的情况。
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;
}),
})
我使用 function
语法而不是箭头函数来验证函数。
文档说:
test functions are called with a special context, or
this
value, that exposes some useful metadata and functions. Note that to usethis
context, the test function must be a function expression(function test(value) {})
, not an arrow function, since arrow functions have lexical context.
这是工作代码。
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);
});
})
});
我也可以用箭头函数来做到这一点。
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);
});
})
});