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.

Having schema dependent on position in array

See original GitHub issue

I have a form with an array of email fields. The form starts with three fields but the user can click a button to add more. I want the first three fields to be required and subsequent fields to be optional (but still validated as emails if filled in).

So I think what I need is a one schema for the first three fields and another for the remaining fields. Trouble is I can’t work out how to determine the current array index from either when or lazy.

I could always model them as separate keys (requiredEmails: yup.array(...), optionalEmails: yup.array(...)) but I wondered if there is a better way.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:16
  • Comments:15 (1 by maintainers)

github_iconTop GitHub Comments

25reactions
Filson14commented, Feb 5, 2019

I don’t have identical issue, but quite similar 😉 I would like to validate an array (let’s assume that it is array of numbers) to check items’ validity based on other items. In a nutshell - if array is defined as sorted,

Any suggestions about how to get other elements’ values while validating single item?

Edit:

I’ve managed array validation with .test() method. @tamlyn, it may be helpful for Your case (but I guess it’s little to late for You 😉 ).

Short fragment of my code is below. Hope it will help someone.

const numberValidation =  yup
  .number()
  .positive("Must be positive")
  .required("Required");

const schema = yup.array(
        yup
          .object({
            price: numberValidation,
            max: numberValidation
          })
          .test("is-threshold-valid", "${path} threshold invalid", function(item) {
            const maxValue = item.max;
            const array = this.parent;
            const index = parseInt(this.path.split("[")[1].split("]")[0], 10);
            const isBigEnough = index ? maxValue > array[index - 1].max : maxValue > 0;
            const isNotToBig = index === array.length - 1 ? true : maxValue < array[index + 1].max;

            return isBigEnough && isNotToBig
              ? true
              : this.createError({path: `${this.path}.max`, message: "Incorrect"});
          })
      )

this inside test function lets us to get parent data, so in case of array we can define validation based on other elements.

8reactions
george-magedcommented, Mar 21, 2019

I had a similar issue and I solved it by creating a custom test function and checking the this.path value

emails: Yup.array().of(
            Yup.string().email('Email must be valid').test('my-test', 'Email is required', function (value) {
                return this.path === "emails[3]" || value
            })
        )

This will work if you have maximum of 4 emails but if you can add more than that you will have to string manipulate this.path to get the index

There might be a better/easier way to get the index but this was what I came up with and I hope it helps

Read more comments on GitHub >

github_iconTop Results From Across the Web

Joi: validate array element depending on index - Stack Overflow
In Joi is there any way to validate elements of an array based on its index? I have this:
Read more >
array — Understanding JSON Schema 2020-12 documentation
There are two ways in which arrays are generally used in JSON: List validation: a sequence of arbitrary length where each item matches...
Read more >
Additional Items - Liquid Technologies
In this example the schema specifies the schemas for first 3 items in the array, if more than 3 items appear in the...
Read more >
<FieldArray /> | Formik
<FieldArray /> is a component that helps with common array/list manipulations. You pass it a name property with the path to the key...
Read more >
Indexing in Azure Cosmos DB - Overview - Microsoft Learn
Azure Cosmos DB is a schema-agnostic database that allows you to iterate on your application without having to deal with schema or index...
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