Как установить динамические сообщения об ошибках при асинхронной проверке Yup?

Я пытаюсь выполнить асинхронную проверку в Formik, используя метод Yup .test(), и мне нужно установить сообщение об ошибке, которое я получаю от API. Сообщения об ошибках будут отличаться в зависимости от некоторых условий в бэкэнде.

Пробовал несколько решений, упомянутых здесь
https://github.com/jquense/yup/issues/222 и сообщения динамической проверки с использованием Yup и Typescript

Но Ага выдает сообщение об ошибке по умолчанию, указанное в test().

В документации говорится, что

Все тесты должны предоставлять имя, сообщение об ошибке и функцию проверки, которая должна возвращать true или false или ValidationError. Чтобы тестовый async возвращал обещание, которое разрешает true или false или 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);
          });
      });
    }
  )
});

person Murli Prajapati    schedule 17.07.2020    source источник
comment
Откуда resolve? это неизвестный импорт   -  person gene b.    schedule 27.05.2021


Ответы (4)


Я заставил его работать с синтаксисом function вместо функции стрелки для функции проверки.

Док говорит:

тестовые функции вызываются со специальным контекстом или значением this, которое предоставляет некоторые полезные метаданные и функции. Обратите внимание, что для использования 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);
        });
    })
});
person Murli Prajapati    schedule 09.09.2020

На самом деле вы почти правы, вам просто нужно использовать следующее:

resolve(this.createError({ message: message }));

Дай мне знать, если это все еще не сработает.

person Lawrence Supian    schedule 03.08.2020
comment
Спасибо! У меня была такая же проблема, и я пропустил то, что недостаточно просто вызвать createError, но вы также должны вернуть результат из своей функции проверки. - person senya; 14.12.2020

Не передавайте второй параметр, поскольку мы обычно передаем его как сообщение об ошибке, вместо этого создайте собственное сообщение с помощью 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;
    }),
})
person Jinks    schedule 02.09.2020

Я также могу сделать это с помощью функции стрелки.

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);
      });
    })
  });
person Arjun G Perambra    schedule 01.06.2021