Reputation: 41
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!
Upvotes: 4
Views: 3036
Reputation: 43
In this code, you have provision to check only first element of array
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(
Yup.object({
name: Yup.string().required('*'),
desc: Yup.string().required('*').max(999, 'maxСharacters' + ' 1000'),
locale: Yup.string().required('*').max(999, 'maxСharacters' + ' 1000')
})
).test('check-first-element', VOYAGE_ERRORS.TRACTOR_RUNWAY, function () {
const { parent } = this;
const firstEle = parent[0];
if (firstEle.name === '' || firstEle.desc === '' || firstEle.locale === '') return false;
return true;
})
})
)
})
Upvotes: 0
Reputation: 889
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...
Upvotes: 5