question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Validation chain order

See original GitHub issue

Hi. Thank you for yup. We love yup much more than joi)

But we stacked with a problem which raised many times: https://github.com/jquense/yup/issues/113 https://github.com/jquense/yup/issues/251 https://github.com/jquense/yup/issues/256 https://github.com/jquense/yup/issues/499 https://github.com/jquense/yup/issues/503 https://github.com/jquense/yup/issues/602

Simple example:

We have an object with field user. This field is required, should be valid MongoDB id and a user with this id should exist in the database.

const schema = yup.object({
  user: yup.string()
    .required()
    .test(someMongoIdValidator)
    .test({
      message: () => 'user is not exists',
      test: async (id) => {
        const user = await User.findById(id);
        return !!user;
      },
    }),
});

No sense to check if mongo id is valid for empty string and of course no sense to make database request (yes, it’s possible to return false if id is empty). We have cases with more reference fields and with arrays of references.

So, we just want to know - are there any plans to implement an option to keep the validation order? Is this consistent with the core idea of yup? Maybe it’s already planned and help is needed.

Or we just have to manage it by multiple schemas and something like “validation waterfall” - apply next schema with only valid fields from the previous schema and merge results at the end.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:36
  • Comments:23 (2 by maintainers)

github_iconTop GitHub Comments

39reactions
ryallcommented, May 13, 2020

I think @codepunkt suggestion was elegant, with .sequence(): https://github.com/jquense/yup/issues/256#issuecomment-406807706

That way it has to be explicitly enabled per rule group:

const schema = yup.object({
  user: yup
    .sequence() // Enabled only for schema.user
    .string()
    .required()
    .test(someMongoIdValidator)
    .test({
      message: () => 'user does not exist',
      test: async (id) => {
        const user = await User.findById(id);
        return !!user;
      },
    }),
  password: yup
    .string()
    .required()
    .min(8)
    .test(someSpecialPasswordTest),
});

In the above case, user and password would validate in parallel, as would the specific rules for password, but the specific rules for user would execute sequentially. If .sequence() was also added to the object schema, then user and password would also validate sequentially.

Alternative names could be sync(), synchronous() or sequenced().

22reactions
Qiming-Liucommented, Feb 24, 2022

@gersondinis @jquense @ryall So, as above, a wrapper method called sequence can be like this:

Yup.addMethod(Yup.string, 'sequence', function (funcList) {
  return this.test(async (value, context) => {
    try {
      for (const func of funcList) {
        await func().validate(value);
      }
    } catch ({ message }) {
      return context.createError({ message });
    }
    return true;
  });
});

Then we can do this:

username: Yup.string().sequence([
        () => Yup.string().max(20).required('Username is required'), // check format
        () => Yup.string().unique('Username is already taken', uniqueUsername),  // check uniqe via api
      ]),

unique is my custom Yup method and uniqueUsername is an axiosInstance

Read more comments on GitHub >

github_iconTop Results From Across the Web

Validation Chain API - express-validator
The validation chain is a middleware, and it should be passed to an Express route handler. You can add as many validators and...
Read more >
Yup dynamic validation chain - Stack Overflow
This method can add conditional validation based off of the value that is being validated, or via a context object that can be...
Read more >
Validator Chains - Laminas Documentation
Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria. ... Setting Validator Chain...
Read more >
Validation using the Chain of Responsibility Pattern
The first step is to break the validator down into individual validators, each responsible for a single implementation of IVehicleModel. We'll ...
Read more >
Validate & Create Order - OpenReference
This may include configuring the product and validating the existence and accuracy of customer data (sold-to, ship-to), pricing information, customer credit and ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found