How to validate with .when statement in yup with parent object - javascript

I have this yup which is works:
const exceptionSchema = yup.object().shape({
exceptionRule: yup.object().shape({
exceptionCondition: yup.object().shape({
exceptionCount: yup.string().required('Exception_Count_Required')
}),
selectedExceptions: yup
.array()
.ensure()
.min(1, 'Validate_ExceptionsAssigned')
})
});
But I have to validate this subobject selectedExceptions when some other property is equals to 1:
and this doesnt work:
const exceptionSchema = yup.object().shape({
exceptionRule: yup.object().shape({
exceptionCondition: yup.object().shape({
exceptionCount: yup.string().required('Exception_Count_Required')
}),
selectedExceptions: yup
.array()
.ensure()
// .min(1, 'Validate_ExceptionsAssigned')
.when('type', {
is: 1,
then: yup
.array()
.ensure()
.min(1, 'Validate_ExceptionsAssigned')
})
})
});
this is mine model, and I think because the type proeprty is not within this object exceptionRule then yup validation does not take into consideration this .when() clause.
Model:
const newRule = () => ({
type: '',
exceptionRule: {
exceptionCondition: {
exceptionCount: '1',
condition: 1,
frequency: 1
},
selectedExceptions: [],
}
});
How to get this type from above, outside my inner object?
How can I debug this when('type') to be sure what value does it have?

Related

yup conditional validation of array

I want to validate the array on the base of loan register if loan register is true then array should validate else not.
yup.object().shape({
loan_register: yup.boolean(),
loans: yup.array()
.of(
yup.object().shape({
bank_name: yup.string().required(),
bank_reg_no: yup.string().required(),
loan_amount: yup.string().required(),
})
)
})
The reason why of is not an exported member from yup is because yup needs to know the type of data first. You can only use of once you know the type.
For example: array().of(), string().oneOf(), e.t.c
Hence, in your case, you need to provide the data type and it will solve your problem.
const validationSchema = yup.object({
loan_register: yup.boolean(),
loans: yup.array().when('loan_register', {
is: true,
then: yup.array().of(
yup.object({
bank_name: yup.string().required(),
bank_reg_no:yup.string().required(),
loan_amount:yup.string().required(),
}))
})
})
EDIT: 'When loan_register === true, bank_name, bank_reg_no and loan_amount must be strings and required fields.'
You can translate that requirement into code like following (include Yup conditional validation using .when() ):
const validationSchema = yup.object().shape({
loan_register: yup.boolean(),
loans: yup.array()
.when('loan_register', {
is: true,
then: yup.of(
yup.object().shape({
bank_name: yup.string().required(),
bank_reg_no: yup.string().required(),
loan_amount: yup.string().required(),
})
)
})
})
I think you'll want to utilize .when(). This allows exactly what you're looking for by providing conditional validation checks based off other attribute values.
It has a more explicit approach where you'd add
.when('loan_register', {is: true, then: /* yup schema */ })
I believe the change would look like
yup.object().shape({
loan_register: yup.boolean(),
loans: yup.array()
.when('loan_register', {
is: true,
then: yup.of(
yup.object().shape({
bank_name: yup.string().required(),
bank_reg_no: yup.string().required(),
loan_amount: yup.string().required(),
})
)
})
})

Yup: Ensure at least one of the elements in an array is valid

I have the following schema:
const baseSchema = {
name: Yup.array().of(
Yup.object().shape({
lang: Yup.string().required(),
value: Yup.string()
.min(2)
.max(20)
.required()
})
)
};
Is there a way to consider the schema valid if at least one of the objects in name is valid?
Edit: essentially it has to use when(), but what I'm struggling with is to find out how to check the other elements in the array.
You can use xor if you want one of them to be required:
const baseSchema = {
name: Yup.array().of(
Yup.object().shape({
lang: Yup.string().required().allow(""),
value: Yup.string()
.min(2)
.max(20)
.required().allow("")
})
)
};

Yup cyclic dependency: Two fields mutually requiring each other

I have the following Yup validation schema
const validationSchema = Yup.object().shape({
name: Yup.string(),
services: Yup.array(Yup.string().oneOf(SERVICES, "Invalid service!")),
locations: Yup.array(Yup.string().oneOf(LOCATIONS, "Invalid location!")),
distance: Yup.number()
.typeError("Invalid distance!")
.positive("Invalid distance!")
.when("userFormattedAddress", {
is: (val) => !!val,
then: Yup.number().required(),
otherwise: Yup.number(),
}),
userFormattedAddress: Yup.string("Invalid user location!").when("distance", {
is: (val) => !!val,
then: Yup.string().required(),
otherwise: Yup.string(),
}),
userCoordinates: Yup.array(
Yup.number("Invalid user location!").positive("Invalid user location!")
),
});
The desired behaviour is that when a distance is entered, the user must enter an address, and when a user enters an address , they must specify a distance too. However, I run into a cyclic dependency... Any thoughts? Thanks!
Okay, I found the answer:
const validationSchema = Yup.object().shape({
name: Yup.string(),
services: Yup.array(Yup.string().oneOf(SERVICES, "Invalid service!")),
locations: Yup.array(Yup.string().oneOf(LOCATIONS, "Invalid location!")),
distance: Yup.number()
.typeError("Invalid distance!")
.positive("Invalid distance!")
.when("userFormattedAddress", {
is: (val) => !!val,
then: Yup.number().required(),
otherwise: Yup.number(),
}),
userFormattedAddress: Yup.string("Invalid user location!").when("distance", {
is: (val) => !!val,
then: Yup.string().required(),
otherwise: Yup.string(),
}),
userCoordinates: Yup.array(
Yup.number("Invalid user location!").positive("Invalid user location!")
),
}, ["distance", "userFormattedAddress"]);
where you need to pass the fields in an array as the noSortedEdges argument

Complex validation using Joi library

I have this json:
let purchaseSubscription = {
'metadata': {
'eventName': 'PurchaseSubscription',
'type': 'setup' // setup, repurchase or recurring
},
'data': {
'subscriptionId': '447481',
'subscriptionTrialId': '23542'
}
};
If the metadata.type has value setup
then data.subscriptionTrialId should be validated for existence and to be a number.
If the metadata.type has other values, the data.subscriptionTrialId can be ignored.
This is what I currently have:
const Joi = require('joi');
const validTypes = ['setup', 'repurchase', 'recurring'];
exports.schema = Joi.object().keys({
metadata: Joi.object({
eventName: Joi.string().required(),
type: Joi.string().valid(validTypes).required()
}).required(),
data: Joi.object({
subscriptionId: Joi.number().integer().min(1).max(2147483647).required(),
subscriptionTrialId: Joi.when(
'metadata.type', { is: 'setup', then: Joi.required() })
}).required()
}).options({ 'allowUnknown': true });
But I am not getting desired results. The data.subscriptionTrialId is always validated, no matter what I have under metadata.type
I tried reading documentation, but can't make it to work :(
You can use the otherwise key in the JOI schema.
Somewhere in your code before declaring exports.schema:
const trialIdRequired = Joi.object({
subscriptionId: Joi.number().integer().min(1).max(2147483647).required(),
subscriptionTrialId: Joi.required()
}).required()
const trialIdNotRequired = Joi.object({
subscriptionId: Joi.number().integer().min(1).max(2147483647).required(),
subscriptionTrialId: Joi.any()
})
And then add a when clause to the data field
data: Joi.when(
'metadata.type',
{
is: 'setup',
then: trialIdRequired,
otherwise: trialIdNotRequired
})

Making one input as required based on the input of another key

I am using JOI for schema validation. In the following schema, I want input_file to be of type required when type is jobType.MBR, otherwise file_name must remain of type required
const jobObjectSchema = {
type: Joi.string().valid(jobType.MBR, jobType.MP4).required(),
file_name: Joi.string().required(),
input_file: Joi.string()
};
How can I do this?
Use Joi any().when.
const jobObjectSchema = {
type: Joi.string().valid(jobType.MBR, jobType.MP4).required(),
file_name: Joi.any().when('type', {
is: jobType.MBR,
then: Joi.string().optional(),
otherwise: Joi.string().required()
}),
input_file: Joi.any().when('type', {
is: jobType.MBR,
then: Joi.string().required(),
otherwise: Joi.string().optional()
})
};

Categories

Resources