Yup: A way to get a dynamic error message in custom `test`?

Created on 22 May 2018  路  4Comments  路  Source: jquense/yup

I want to have a custom validator, which runs a function with the provided value and the error message is the output of that function. How can I accomplish that with yup?
It looks like nonetheless I can run any custom code in the validator function itself, the error message is just a string

Most helpful comment

This works for me:

const validationSchema = Yup.object().shape({
  fieldName: Yup.string().test({
    name: 'validator-custom-name',
    // eslint-disable-next-line object-shorthand
    test: function(value) {
      // You can add any logic here to generate a dynamic message

      return value === 1
        ? this.createError({
            message: `Custom Message here ${value}`,
            path: 'fieldName', // Fieldname
          })
        : true;
    },
  }),

  // All other fields to validate....
});


All 4 comments

So validator is just a function that checks if condition is met and sets error message if it's not.
Could you give an example of validation you want to create?

In cases like email validation you could use validators chaining to check if value is a string, then if it's not empty and after that if provided value is an email.

yup.string().required().email()

validator functions have access to a bunch of options there for that. check out the tests for createError which lets you control exactly waht message, path, etc is used for a failed test. https://github.com/jquense/yup/blob/4088e7d6728dad1eee9e0e3bb7570b09ceba7de5/test/mixed.js#L445

@jquense I'm trying to do define a custom method called, let's say, "equals"

it does a test check but I wanted to define the error messages the same place where I define my localized error messages using setLocale

If I return this.createError(); it will aways go to mixed.default error message with custom path and without.

Is there a way I can make the error go to whatever match I set it to?

Example:

yup.addMethod(yup.string, 'equals', function (key) {
  return this.test(
    'equals', 
    function () {
      return this.createError();
    },
    function (value) {
      return value === yup.ref(key);
    }
  );
});

And then set it like

yup.setLocale({
...
string: {
  ...
  equals: "blablabla error equals",
},
...
});

This works for me:

const validationSchema = Yup.object().shape({
  fieldName: Yup.string().test({
    name: 'validator-custom-name',
    // eslint-disable-next-line object-shorthand
    test: function(value) {
      // You can add any logic here to generate a dynamic message

      return value === 1
        ? this.createError({
            message: `Custom Message here ${value}`,
            path: 'fieldName', // Fieldname
          })
        : true;
    },
  }),

  // All other fields to validate....
});


Was this page helpful?
0 / 5 - 0 ratings