How to validate a list of emails like [email protected];[email protected]
I tried to convert the string to an array and validate each email like this, but it's difficult to mix strings and arrays:
yup.array().transform((str) => str.split(';')).of(yup.string().email()).required()
what's wrong with your example? Does it not work?
It is applied on a text input containing: [email protected];[email protected]. Since that is a String and not an Array, the transform receives a null
The original value actually has this data, so this works without the required
yup.array().transform((str) => str.split(';')).of(yup.string().email()).required()
With required, I'm getting Cannot read property 'length' of undefined probably because it's reading the value and not originalValue
probably because it's reading the value and not originalValue
O right, yes you should use originalValue here, since value will be null or empty b/c the built in array parsing will have failed
I'm getting a similar issue where my initial value starts off as an array, but as soon as I type something the entire value becomes a string and no string validations are performed
I had to do this recently and ended up with the following. Maybe it'll help someone else?
const isEmail = (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value); // or use your own
const EmailFormValidationSchema = object().shape({
body: string().required(),
recipient: string()
.transform((value) => Array.from(new Set(value.split(';'))).join(';')) // dedupe - optional step
.required()
.test(
'emails',
'Invalid email address',
(value) => value && value.split(';').every(isEmail)
),
subject: string().required(),
});
This solution transforms a comma delimited string into an array of emails and then performs email validation on each one.
const validationSchema = Yup.object().shape({
email: Yup.array()
.transform(function(value, originalValue) {
if (this.isType(value) && value !== null) {
return value;
}
return originalValue ? originalValue.split(/[\s,]+/) : [];
})
.of(Yup.string().email(({ value }) => `${value} is not a valid email`)),
});
If this is useful to anybody:
const isEmailSchema = Yup.string().email();
const schema = Yup.object().shape({
"email-list": yup
.string()
.required("This field cannot be empty")
.test({
name: "emails",
test: function(value) {
const firstInvalidEmail = value
.split(",")
.map(email => email.trim())
.filter(v => !isEmpty(v))
.find(v => !isEmailSchema.isValidSync(v));
return !firstInvalidEmail
? true
: this.createError({
message: `The email address '${firstInvalidEmail}' is invalid.`
});
}
})
});
Most helpful comment
This solution transforms a comma delimited string into an array of emails and then performs email validation on each one.