Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YupSchema. how validate only first element of array in YupSchema

I have this schema:

const YupSchema = (t: TFunction) =>
Yup.object().shape({
    name: Yup.string()
        .required('*')
        .max(49, 'maxСharacters' + ' 50'),
    areas: Yup.array().required('*'),        
    activities: Yup.array().of(
        Yup.object().shape({
            id: Yup.string().required('*'),
            pictureGood: Yup.string().required(
                'Required'
            ),
            pictureBad: Yup.string().required(
                'Required'
            ),
            translations: Yup.array() /* <=== hear I need get only first element in array*/
                .of(
                    Yup.object().shape({
                        name: Yup.string().required('*'),
                        desc: Yup.string()
                            .required('*')
                            .max(999, 'maxСharacters' + ' 1000'),
                       
                        locale: Yup.string()
                            .required('*')
                            .max(999, 'maxСharacters' + ' 1000')
                    })
                )
                .required('Translations Required')
        })
    )
})

For this data object:

[{"id":"","activitiId":"1","pictureGood":[],"pictures":[],"translations":[{"generalDesc":"test","descGood":"test","descBad":"test","locale":"IT"},"generalDesc":"test","descGood":"test","descBad":"test","locale":"EN"}]}]

But I need to validate only the first element in the array, not all. something like this: .

...

translations: Yup.array()[0]
            .of(
                Yup.object().shape({
                    name: Yup.string().required('*'),

...

Thanks for the answers!

like image 991
Valerii Pushkar Avatar asked Oct 24 '25 05:10

Valerii Pushkar


1 Answers

I wanted to do the same, and I could see the "index" property coming in once I extended my "from" object as per: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/49512 ...but I couldn't get at the index.

So using that technique (which I'll copy below for full answer here) I managed to ALSO extend the "options" object coming from the TextContext, then extend the "ValidateOptions" object (which I could see by stepping through in the browser where I could see index values!) - and therefore I could check which index I was at for my test in the array (as it loops through all items in the array).

I run this yup.test() over the array, and simply chuck out anything that wasn't index=0 for example (index === 0 in react/javascript of course!).

So my solution is:

interface ValidateOptionsExtended {
    options: {
        index: number;
    };
}

Yup.array().of(
    Yup.object().shape({
         outletId: yup
            .string()
            .trim()
            .nullable()
            .test('firstOutletAlwaysMandatory', 'Organisation name is required', function (item) {
                        const { from } = this as yup.TestContext & TestContextExtended;
                        const { options } = this as yup.TestContext & ValidateOptionsExtended;
                        // if not index 0 then exit we are not checking others here
                        if (options.index > 0) {
                           return true; 
                        }

                        ...check required value etc for index 0 here...
like image 93
Davemundo Avatar answered Oct 27 '25 03:10

Davemundo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!