Библиотека Validator.js изначально ориентирована на проверку строковых значений, однако в реальных приложениях часто возникает необходимость работать с наборами данных: списками email-адресов, массивами телефонов, динамическими формами и вложенными структурами. В таких случаях базовые функции библиотеки дополняются логикой обхода коллекций и агрегации результатов валидации.
Основной принцип обработки множественных полей заключается в том, что каждое значение внутри коллекции проверяется независимо, а итоговый результат формируется на основе совокупности проверок.
При работе с массивами строк Validator.js применяется через итерацию
по элементам. Каждое значение проходит стандартные проверки, такие как
isEmail, isLength, isNumeric.
import validator from 'validator';
const emails = [
'user@example.com',
'invalid-email',
'admin@site.org'
];
const results = emails.map(email => validator.isEmail(email));
Такой подход позволяет сохранить простоту API библиотеки, поскольку Validator.js не требует специальной поддержки массивов — обработка выполняется на уровне приложения.
Расширенная проверка часто включает фильтрацию корректных и некорректных значений:
const validEmails = emails.filter(email => validator.isEmail(email));
const invalidEmails = emails.filter(email => !validator.isEmail(email));
При обработке списков контактных данных важна не только проверка формата, но и унификация входных значений.
const phones = [
'+77001234567',
'87001234567',
'invalid-phone'
];
const normalizedPhones = phones.map(phone => validator.trim(phone));
const validPhones = normalizedPhones.filter(phone =>
validator.isMobilePhone(phone, 'any')
);
В подобных сценариях применяется предварительная нормализация, включающая удаление пробелов, приведение формата и фильтрацию пустых значений.
В динамических формах количество полей заранее неизвестно. Например, пользователь может добавлять произвольное число контактов или адресов. В таких случаях структура данных представляет собой массив объектов.
const formData = {
users: [
{ email: 'first@example.com', age: '25' },
{ email: 'wrong-email', age: '17' }
]
};
Проверка выполняется через обход массива и валидацию каждого поля объекта:
const errors = [];
formData.users.forEach((user, index) => {
if (!validator.isEmail(user.email)) {
errors.push({ index, field: 'email' });
}
if (!validator.isInt(user.age, { min: 18 })) {
errors.push({ index, field: 'age' });
}
});
Такой подход позволяет сохранять связь между ошибкой и конкретным элементом массива, что особенно важно при отображении ошибок в интерфейсе.
Стандартный набор Validator.js не включает встроенные средства для работы с массивами, поэтому часто создаются вспомогательные функции.
function validateArray(array, validateFn) {
return array.map((value, index) => ({
index,
valid: validateFn(value)
}));
}
Применение:
const result = validateArray(emails, validator.isEmail);
Более сложные сценарии включают комбинированную проверку:
function validateUsers(users) {
return users.map(user => ({
email: validator.isEmail(user.email),
age: validator.isInt(user.age, { min: 18 })
}));
}
Часто перед валидацией выполняется преобразование структуры данных. Это особенно актуально при работе с формами, где значения приходят в виде строк.
const rawValues = [' 10 ', '20', ' 30'];
const numbers = rawValues
.map(value => validator.trim(value))
.map(value => Number(value));
const validNumbers = numbers.filter(value =>
validator.isInt(String(value))
);
Преобразование и валидация часто разделяются на отдельные этапы, что упрощает поддержку кода и повышает читаемость логики обработки данных.
При работе с коллекциями данных важно формировать структурированный результат ошибок. Вместо простого булевого результата используется объект, содержащий подробную информацию.
const errors = {};
emails.forEach((email, index) => {
if (!validator.isEmail(email)) {
errors[index] = 'Некорректный email';
}
});
Более универсальная структура включает группировку по полям:
const errors = {
emails: [],
phones: []
};
emails.forEach((email, index) => {
if (!validator.isEmail(email)) {
errors.emails.push(index);
}
});
Такой формат упрощает интеграцию с интерфейсами форм, где ошибки отображаются на уровне конкретных полей.
В реальных приложениях данные часто имеют вложенную структуру, где массивы содержат объекты с несколькими полями. В таких случаях применяется рекурсивная или многоуровневая проверка.
const data = {
orders: [
{
id: '1',
amount: '100',
email: 'client@example.com'
},
{
id: '2',
amount: 'invalid',
email: 'wrong-email'
}
]
};
Проверка:
const result = data.orders.map(order => ({
id: order.id,
amountValid: validator.isNumeric(order.amount),
emailValid: validator.isEmail(order.email)
}));
При необходимости добавляется агрегация общего состояния:
const hasErrors = result.some(r => !r.amountValid || !r.emailValid);
При увеличении сложности данных применяется унифицированный подход, основанный на конфигурации правил.
const rules = {
email: validator.isEmail,
age: value => validator.isInt(value, { min: 18 })
};
function validateObject(obj, rules) {
const result = {};
Object.keys(rules).forEach(key => {
result[key] = rules[key](obj[key]);
});
return result;
}
Для массивов объектов:
const validated = users.map(user => validateObject(user, rules));
Такой подход позволяет отделить структуру данных от логики проверки и упростить масштабирование системы валидации.