ValidationChain
The validation chain contains all of the built-in validators, sanitizers and utility methods to fine tune the behaviour of the validation for a certain field or fields.
Validation chains are created by the check()
functions, and they can be used in a few ways:
- as express.js route handlers, which will run the validation automatically;
- as parameter of some of express-validator's other functions, like
oneOf()
orcheckExact()
; - standalone, where you have full control over when the validation runs and how.
If you're writing a function that accepts a ValidationChain
, the TypeScript type can be imported using
import { ValidationChain } from 'express-validator';
Built-in validators
.custom()
custom(validator: (value, { req, location, path }) => any): ValidationChain
Adds a custom validator function to the chain.
The field value will be valid if:
- The custom validator returns truthy; or
- The custom validator returns a promise that resolves.
If the custom validator returns falsy, a promise that rejects, or if the function throws, then the value will be considered invalid.
A common use case for .custom()
is to verify that an e-mail address doesn't already exists.
If it does, return an error:
app.post(
'/signup',
body('email').custom(async value => {
const existingUser = await Users.findUserByEmail(value);
if (existingUser) {
throw new Error('E-mail already in use');
}
}),
(req, res) => {
// Handle request
},
);
.exists()
exists(options?: {
values?: 'undefined' | 'null' | 'falsy',
checkNull?: boolean,
checkFalsy?: boolean
}): ValidationChain
Adds a validator to check if the field exists.
Which values are considered existent depends on options.values
. By default, it's set to undefined
:
options.values | Behavior |
---|---|
undefined | undefined values don't exist |
null | undefined and null values don't exist |
falsy | Falsy values (empty strings, 0 , false , null and undefined values don't exist |
options.checkNull
and options.checkFalsy
are deprecated options.
They are aliases to setting options.values
to null
and falsy
, respectively.
Using .exists()
is only necessary if you aren't adding any other validator or sanitizer.
.isArray()
isArray(options?: { min?: number; max?: number }): ValidationChain
Adds a validator to check that a value is an array.
This is analogous to the JavaScript function Array.isArray(value)
.
You can also check that the array's length is greater than or equal to options.min
and/or
that it's less than or equal to options.max
.
// Verifies that the friends list is an array
body('friends').isArray();
// Verifies that ingredients is an array with length >= 0
body('ingredients').isArray({ min: 0 });
// Verifies that team_members is an array with length >= 0 and <= 10
check('team_members').isArray({ min: 0, max: 10 });
.isObject()
isObject(options?: { strict?: boolean }): ValidationChain
Adds a validator to check that a value is an object.
For example, {}
, { foo: 'bar' }
and new MyCustomClass()
would all pass this validator.
If the strict
option is set to false
, then this validator works analogous to
typeof value === 'object'
in pure JavaScript,
where both arrays and the null
value are considered objects.
.isString()
isString(): ValidationChain
Adds a validator to check that a value is a string.
This is analogous to a typeof value === 'string'
in pure JavaScript.
.notEmpty()
notEmpty(): ValidationChain
Adds a validator to check that a value is a string that's not empty.
This is analogous to .not().isEmpty()
.
Standard validators
Please check the documentation on standard validators here.
contains()
contains(elem: any, options?: {
ignoreCase?: boolean;
minOccurrences?: number;
}): ValidationChain
equals()
equals(comparison: string): ValidationChain
isAfter()
isAfter(dateOrOptions?: string | {
comparisonDate?: string;
}): ValidationChain
isAlpha()
isAlpha(locale?: AlphaLocale, options?: {
ignore?: string | string[] | RegExp;
}): ValidationChain
Possible values of AlphaLocale
'ar'
'ar-AE'
'ar-BH'
'ar-DZ'
'ar-EG'
'ar-IQ'
'ar-JO'
'ar-KW'
'ar-LB'
'ar-LY'
'ar-MA'
'ar-QA'
'ar-QM'
'ar-SA'
'ar-SD'
'ar-SY'
'ar-TN'
'ar-YE'
'az-AZ'
'bg-BG'
'bn-BD'
'cs-CZ'
'da-DK'
'de-DE'
'el-GR'
'en-AU'
'en-GB'
'en-HK'
'en-IN'
'en-NZ'
'en-US'
'en-ZA'
'en-ZM'
'es-ES'
'fa-AF'
'fa-IR'
'fi-FI'
'fr-FR'
'he'
'hi-IN'
'hu-HU'
'id-ID'
'it-IT'
'ja-JP'
'ko-KR'
'ku-IQ'
'nb-NO'
'nl-NL'
'nn-NO'
'pl-PL'
'pt-BR'
'pt-PT'
'ru-RU'
'si-LK'
'sk-SK'
'sl-SI'
'sr-RS'
'sr-RS@latin'
'sv-SE'
'th-TH'
'tr-TR'
'uk-UA'
'vi-VN'
isAlphanumeric()
isAlphanumeric(locale?: AlphanumericLocale, options?: {
ignore?: string | RegExp;
}): ValidationChain
Possible values of AlphanumericLocale
'ar'
'ar-AE'
'ar-BH'
'ar-DZ'
'ar-EG'
'ar-IQ'
'ar-JO'
'ar-KW'
'ar-LB'
'ar-LY'
'ar-MA'
'ar-QA'
'ar-QM'
'ar-SA'
'ar-SD'
'ar-SY'
'ar-TN'
'ar-YE'
'az-AZ'
'bg-BG'
'bn-BD'
'cs-CZ'
'da-DK'
'de-DE'
'el-GR'
'en-AU'
'en-GB'
'en-HK'
'en-IN'
'en-NZ'
'en-US'
'en-ZA'
'en-ZM'
'es-ES'
'fa-AF'
'fa-IR'
'fi-FI'
'fr-FR'
'fr-BE'
'he'
'hi-IN'
'hu-HU'
'it-IT'
'id-ID'
'ja-JP'
'ko-KR'
'ku-IQ'
'nb-NO'
'nl-BE'
'nl-NL'
'nn-NO'
'pl-PL'
'pt-BR'
'pt-PT'
'ru-RU'
'si-LK'
'sk-SK'
'sl-SI'
'sr-RS'
'sr-RS@latin'
'sv-SE'
'th-TH'
'tr-TR'
'uk-UA'
'vi-VN'
isAscii()
isAscii(): ValidationChain
isBase32()
isBase32(options?: {
crockford?: boolean;
}): ValidationChain
isBase58()
isBase58(): ValidationChain
isBase64()
isBase64(options?: {
urlSafe?: boolean;
}): ValidationChain
isBefore()
isBefore(date?: string): ValidationChain
isBIC()
isBIC(): ValidationChain
isBoolean()
isBoolean(options?: {
strict?: boolean;
loose?: boolean;
}): ValidationChain
isBtcAddress()
isBtcAddress(): ValidationChain
isByteLength()
isByteLength(options: {
min?: number;
max?: number;
lt?: number;
gt?: number;
}): ValidationChain
isCreditCard()
isCreditCard(options?: {
provider?: 'amex' | 'dinersclub' | 'discover' | 'jcb' | 'mastercard' | 'unionpay' | 'visa';
}): ValidationChain
isCurrency()
isCurrency(options?: {
symbol?: string;
require_symbol?: boolean;
allow_space_after_symbol?: boolean;
symbol_after_digits?: boolean;
allow_negatives?: boolean;
parens_for_negatives?: boolean;
negative_sign_before_digits?: boolean;
negative_sign_after_digits?: boolean;
allow_negative_sign_placeholder?: boolean;
thousands_separator?: string;
decimal_separator?: string;
allow_decimal?: boolean;
require_decimal?: boolean;
digits_after_decimal?: number[];
allow_space_after_digits?: boolean;
}): ValidationChain
isDataURI()
isDataURI(): ValidationChain
isDate()
isDate(options?: {
format?: string;
delimiters?: string[];
strictMode?: boolean;
}): ValidationChain
isDecimal()
isDecimal(options?: {
decimal_digits?: string;
force_decimal?: boolean;
locale?: AlphanumericLocale;
blacklisted_chars?: string;
}): ValidationChain
isDivisibleBy()
isDivisibleBy(number: number): ValidationChain
isEAN()
isEAN(): ValidationChain
isEmail()
isEmail(options?: {
allow_display_name?: boolean;
allow_utf8_local_part?: boolean;
require_tld?: boolean;
ignore_max_length?: boolean;
allow_ip_domain?: boolean;
domain_specific_validation?: boolean;
blacklisted_chars?: string;
host_blacklist?: string[];
host_whitelist?: string[];
}): ValidationChain
isEmpty()
isEmpty(options?: {
ignore_whitespace: boolean;
}): ValidationChain
isEthereumAddress()
isEthereumAddress(): ValidationChain
isFQDN()
isFQDN(options?: {
require_tld?: boolean;
allow_underscores?: boolean;
allow_trailing_dot?: boolean;
allow_numeric_tld?: boolean;
allow_wildcard?: boolean;
ignore_max_length?: boolean;
}): ValidationChain
isFloat()
isFloat(options?: {
min?: number;
max?: number;
lt?: number;
gt?: number;
locale?: AlphanumericLocale;
}): ValidationChain
isFullWidth()
isFullWidth(): ValidationChain
isHalfWidth()
isHalfWidth(): ValidationChain
isHash()
isHash(algorithm: HashAlgorithm): ValidationChain
Possible values of HashAlgorithm
'md4'
'md5'
'sha1'
'sha256'
'sha384'
'sha512'
'ripemd128'
'ripemd160'
'tiger128'
'tiger160'
'tiger192'
'crc32'
'crc32b'
isHexColor()
isHexColor(): ValidationChain
isHexadecimal()
isHexadecimal(): ValidationChain
isHSL()
isHSL(): ValidationChain
isIBAN()
isIBAN(): ValidationChain
isIdentityCard()
isIdentityCard(locale?: IdentityCardLocale): ValidationChain
Possible values of IdentityCardLocale
'any'
'ar-LY'
'ar-TN'
'ES'
'FI'
'he-IL'
'hk-HK'
'IN'
'IT'
'IR'
'MZ'
'NO'
'PL'
'TH'
'zh-CN'
'zh-TW'
isIMEI()
isIMEI(options?: {
allow_hyphens?: boolean;
}): ValidationChain
isIP()
isIP(version?: 4 | 6): ValidationChain
isIPRange()
isIPRange(version?: 4 | 6): ValidationChain
isISBN()
isISBN(versionOrOptions?: number | {
version?: '10' | '13';
}): ValidationChain
isISSN()
isISSN(options?: {
case_sensitive?: boolean;
require_hyphen?: boolean;
}): ValidationChain
isISIN()
isISIN(): ValidationChain
isISO6391()
isISO6391(): ValidationChain
isISO8601()
isISO8601(options?: {
strict?: boolean;
strictSeparator?: boolean;
}): ValidationChain
isISO31661Alpha2()
isISO31661Alpha2(): ValidationChain
isISO31661Alpha3()
isISO31661Alpha3(): ValidationChain
isISO4217()
isISO4217(): ValidationChain
isISRC()
isISRC(): ValidationChain
isIn()
isIn(values: readonly any[]): ValidationChain
isInt()
isInt(options?: {
min?: number;
max?: number;
lt?: number;
gt?: number;
allow_leading_zeroes?: boolean;
}): ValidationChain
isJSON()
isJSON(options?: {
allow_primitives?: boolean;
}): ValidationChain
isJWT()
isJWT(): ValidationChain
isLatLong()
isLatLong(options?: {
checkDMS?: boolean;
}): ValidationChain
isLength()
isLength(options: {
min?: number;
max?: number;
}): ValidationChain
isLicensePlate()
isLicensePlate(locale: IsLicensePlateLocale): ValidationChain
Possible values of IsLicensePlateLocale
'cs-CZ'
'de-DE'
'de-LI'
'en-NI'
'es-AR'
'fi-FI'
'hu-HU'
'pt-BR'
'pt-PT'
'sq-AL'
'sv-SE'
'any'
isLocale()
isLocale(): ValidationChain
isLowercase()
isLowercase(): ValidationChain
isLuhnNumber()
isLuhnNumber(): ValidationChain
isMagnetURI()
isMagnetURI(): ValidationChain
isMACAddress()
isMACAddress(options?: {
no_separators?: boolean;
no_colons?: boolean;
eui?: '48' | '64';
}): ValidationChain
isMD5()
isMD5(): ValidationChain
isMimeType()
isMimeType(): ValidationChain
isMobilePhone()
isMobilePhone(locale: MobilePhoneLocale | readonly Options.MobilePhoneLocale[], options?: {
strictMode?: boolean;
}): ValidationChain
Possible values of MobilePhoneLocale
'any'
'am-AM'
'ar-AE'
'ar-BH'
'ar-DZ'
'ar-EG'
'ar-EH'
'ar-IQ'
'ar-JO'
'ar-KW'
'ar-LB'
'ar-LY'
'ar-MA'
'ar-OM'
'ar-PS'
'ar-SA'
'ar-SY'
'ar-TN'
'ar-YE'
'az-AZ'
'be-BY'
'bg-BG'
'bn-BD'
'bs-BA'
'cs-CZ'
'de-AT'
'de-CH'
'de-DE'
'de-LU'
'da-DK'
'dv-MV'
'dz-BT'
'el-CY'
'el-GR'
'en-AG'
'en-AI'
'en-AU'
'en-BM'
'en-BS'
'en-BW'
'en-CA'
'en-GB'
'en-GG'
'en-GH'
'en-GY'
'en-HK'
'en-HN'
'en-IE'
'en-IN'
'en-JM'
'en-KE'
'en-KI'
'en-KN'
'en-LS'
'en-MT'
'en-MU'
'en-NA'
'en-NG'
'en-NZ'
'en-PG'
'en-PH'
'en-PK'
'en-RW'
'en-SG'
'en-SL'
'en-SS'
'en-TZ'
'en-UG'
'en-US'
'en-ZA'
'en-ZM'
'en-ZW'
'es-AR'
'es-BO'
'es-CL'
'es-CO'
'es-CR'
'es-CU'
'es-DO'
'es-EC'
'es-ES'
'es-HN'
'es-MX'
'es-NI'
'es-PA'
'es-PE'
'es-PY'
'es-SV'
'es-UY'
'es-VE'
'et-EE'
'fa-AF'
'fa-IR'
'fi-FI'
'fj-FJ'
'fo-FO'
'fr-BE'
'fr-BF'
'fr-BJ'
'fr-CD'
'fr-CH'
'fr-CM'
'fr-FR'
'fr-GF'
'fr-GP'
'fr-MQ'
'fr-PF'
'fr-RE'
'ga-IE'
'he-IL'
'hu-HU'
'id-ID'
'ir-IR'
'it-CH'
'it-IT'
'it-SM'
'ja-JP'
'ka-GE'
'kk-KZ'
'kl-GL'
'ko-KR'
'ky-KG'
'lt-LT'
'lv-LV'
'mg-MG'
'mn-MN'
'ms-MY'
'my-MM'
'mz-MZ'
'nb-NO'
'nl-AW'
'nl-BE'
'nl-NL'
'ne-NP'
'nn-NO'
'pl-PL'
'pt-AO'
'pt-BR'
'pt-PT'
'ro-MD'
'ro-RO'
'ru-RU'
'si-LK'
'sk-SK'
'sl-SI'
'sq-AL'
'sr-RS'
'sv-SE'
'tg-TJ'
'th-TH'
'tk-TM'
'tr-TR'
'uk-UA'
'uz-Uz'
'vi-VN'
'zh-CN'
'zh-HK'
'zh-TW'
isMongoId()
isMongoId(): ValidationChain
isMultibyte()
isMultibyte(): ValidationChain
isNumeric()
isNumeric(options?: {
no_symbols: boolean;
locale?: AlphanumericLocale;
}): ValidationChain
isOctal()
isOctal(): ValidationChain
isPassportNumber()
isPassportNumber(countryCode?: PassportCountryCode): ValidationChain
Possible values of PassportCountryCode
'AM'
'AR'
'AT'
'AU'
'AZ'
'BE'
'BG'
'BY'
'BR'
'CA'
'CH'
'CN'
'CY'
'CZ'
'DE'
'DK'
'DZ'
'EE'
'ES'
'FI'
'FR'
'GB'
'GR'
'HR'
'HU'
'ID'
'IE'
'IN'
'IR'
'IS'
'IT'
'JM'
'JP'
'KR'
'KZ'
'LI'
'LT'
'LU'
'LV'
'LY'
'MT'
'MY'
'MZ'
'NL'
'NZ'
'PH'
'PK'
'PL'
'PO'
'PT'
'RO'
'RU'
'SE'
'SL'
'SK'
'TH'
'TR'
'UA'
'US'
isPort()
isPort(): ValidationChain
isPostalCode()
isPostalCode(locale: PostalCodeLocale): ValidationChain
Possible values of PostalCodeLocale
'any'
'AD'
'AT'
'AU'
'AZ'
'BA'
'BE'
'BG'
'BR'
'BY'
'CA'
'CH'
'CN'
'CZ'
'DE'
'DK'
'DO'
'DZ'
'EE'
'ES'
'FI'
'FR'
'GB'
'GR'
'HR'
'HT'
'HU'
'ID'
'IL'
'IN'
'IR'
'IS'
'IT'
'JP'
'KE'
'KR'
'LI'
'LK'
'LT'
'LU'
'LV'
'MT'
'MX'
'MY'
'NL'
'NO'
'NP'
'NZ'
'PL'
'PR'
'PT'
'RO'
'RU'
'SA'
'SE'
'SG'
'SI'
'SK'
'TH'
'TN'
'TW'
'UA'
'US'
'ZA'
'ZM'
isRgbColor()
isRgbColor(includePercentValues?: boolean): ValidationChain
isRFC3339()
isRFC3339(): ValidationChain
isSemVer()
isSemVer(): ValidationChain
isSlug()
isSlug(): ValidationChain
isStrongPassword()
isStrongPassword(options?: {
minLength?: number;
minLowercase?: number;
minUppercase?: number;
minNumbers?: number;
minSymbols?: number;
returnScore?: boolean;
pointsPerUnique?: number;
pointsPerRepeat?: number;
pointsForContainingLower?: number;
pointsForContainingUpper?: number;
pointsForContainingNumber?: number;
pointsForContainingSymbol?: number;
}): ValidationChain
isSurrogatePair()
isSurrogatePair(): ValidationChain
isTaxID()
isTaxID(locale: TaxIDLocale): ValidationChain
Possible values of TaxIDLocale
'bg-BG'
'cs-CZ'
'de-AT'
'de-DE'
'dk-DK'
'el-CY'
'el-GR'
'en-CA'
'en-GB'
'en-IE'
'en-US'
'es-ES'
'et-EE'
'fi-FI'
'fr-BE'
'fr-FR'
'fr-LU'
'hr-HR'
'hu-HU'
'it-IT'
'lb-LU'
'lt-LT'
'lv-LV'
'mt-MT'
'nl-BE'
'nl-NL'
'pl-PL'
'pt-BR'
'pt-PT'
'ro-RO'
'sk-SK'
'sl-SI'
'sv-SE'
isTime()
isTime(options: {
hourFormat?: 'hour24' | 'hour12';
mode?: 'default' | 'withSeconds';
}): ValidationChain
isURL()
isURL(options?: {
protocols?: URLProtocol[];
require_tld?: boolean;
require_protocol?: boolean;
require_host?: boolean;
require_port?: boolean;
require_valid_protocol?: boolean;
allow_underscores?: boolean;
host_whitelist?: (string | RegExp)[];
host_blacklist?: (string | RegExp)[];
allow_trailing_dot?: boolean;
allow_protocol_relative_urls?: boolean;
disallow_auth?: boolean;
validate_length?: boolean;
allow_fragments?: boolean;
allow_query_components?: boolean;
}): ValidationChain
isUUID()
isUUID(version?: UUIDVersion): ValidationChain
Possible values of UUIDVersion
1
2
3
4
5
'1'
'2'
'3'
'4'
'5'
'all'
isUppercase()
isUppercase(): ValidationChain
isVariableWidth()
isVariableWidth(): ValidationChain
isVAT()
isVAT(countryCode: VATCountryCode): ValidationChain
Possible values of VATCountryCode
'GB'
'IT'
'NL'
'AT'
'BE'
'BG'
'HR'
'CY'
'CZ'
'DK'
'EE'
'FI'
'FR'
'DE'
'EL'
'HU'
'IE'
'LV'
'LT'
'LU'
'MT'
'PL'
'PT'
'RO'
'SK'
'SI'
'ES'
'SE'
'AL'
'MK'
'AU'
'BY'
'CA'
'IS'
'IN'
'ID'
'IL'
'KZ'
'NZ'
'NG'
'NO'
'PH'
'RU'
'SM'
'SA'
'RS'
'CH'
'TR'
'UA'
'UZ'
'AR'
'BO'
'BR'
'CL'
'CO'
'CR'
'EC'
'SV'
'GT'
'HN'
'MX'
'NI'
'PA'
'PY'
'PE'
'DO'
'UY'
'VE'
isWhitelisted()
isWhitelisted(chars: string | readonly string[]): ValidationChain
matches()
matches(pattern: RegExp | string, modifiers?: string): ValidationChain
Built-in sanitizers
.customSanitizer()
customSanitizer(sanitizer: (value, { req, location, path }) => any): ValidationChain
Adds a custom sanitizer function to the chain. The value returned by the function will become the new value of the field.
app.post('/object/:id', param('id').customSanitizer((value, { req }) => {
// In this app, users have MongoDB style object IDs, everything else, numbers
return req.query.type === 'user' ? ObjectId(value) : Number(value);
})), (req, res) => {
// Handle request
});
.default()
default(defaultValue: any): ValidationChain
Replaces the value of the field if it's either an empty string, null
, undefined
, or NaN
.
app.post('/', body('username').default('foo'), (req, res, next) => {
// 'bar' => 'bar'
// '' => 'foo'
// undefined => 'foo'
// null => 'foo'
// NaN => 'foo'
});
.replace()
replace(valuesFrom: any[], valueTo: any): ValidationChain
Replaces the value of the field with valueTo
whenever the current value is in valuesFrom
.
app.post('/', body('username').replace(['bar', 'BAR'], 'foo'), (req, res, next) => {
// 'bar_' => 'bar_'
// 'bar' => 'foo'
// 'BAR' => 'foo'
console.log(req.body.username);
});
.toArray()
toArray(): ValidationChain
Transforms the value to an array. If it already is one, nothing is done. undefined
values become empty arrays.
.toLowerCase()
toLowerCase(): ValidationChain
Converts the value to lower case. If not a string, does nothing.
.toUpperCase()
toUpperCase(): ValidationChain
Converts the value to upper case. If not a string, does nothing.
Standard sanitizers
Please check the documentation on standard sanitizers here.
blacklist()
blacklist(chars: string): ValidationChain
escape()
escape(): ValidationChain
unescape()
unescape(): ValidationChain
ltrim()
ltrim(chars?: string): ValidationChain
normalizeEmail()
normalizeEmail(options?: {
all_lowercase?: boolean;
gmail_lowercase?: boolean;
gmail_remove_dots?: boolean;
gmail_remove_subaddress?: boolean;
gmail_convert_googlemaildotcom?: boolean;
outlookdotcom_lowercase?: boolean;
outlookdotcom_remove_subaddress?: boolean;
yahoo_lowercase?: boolean;
yahoo_remove_subaddress?: boolean;
icloud_lowercase?: boolean;
icloud_remove_subaddress?: boolean;
}): ValidationChain
rtrim()
rtrim(chars?: string): ValidationChain
stripLow()
stripLow(keep_new_lines?: boolean): ValidationChain
toBoolean()
toBoolean(strict?: boolean): ValidationChain
toDate()
toDate(): ValidationChain
toFloat()
toFloat(): ValidationChain
toInt()
toInt(radix?: number): ValidationChain
trim()
trim(chars?: string): ValidationChain
whitelist()
whitelist(chars: string): ValidationChain
Modifiers
.bail()
bail(options?: { level: 'chain' | 'request' }): ValidationChain
Parameters:
Name | Description |
---|---|
options.level | The level at which the validation chain should be stopped. Defaults to chain . |
Stops running the validation chain if any of the previous validators failed.
This is useful to prevent a custom validator that touches a database or external API from running when you know it will fail.
.bail()
can be used multiple times in the same validation chain if desired:
body('username')
.isEmail()
// If not an email, stop here
.bail()
.custom(checkDenylistDomain)
// If domain is not allowed, don't go check if it already exists
.bail()
.custom(checkEmailExists);
If the level
option is set to request
, then also no further validation chains will run on the current request.
For example:
app.get(
'/search',
query('query').notEmpty().bail({ level: 'request' }),
// If `query` is empty, then the following validation chains won't run:
query('query_type').isIn(['user', 'posts']),
query('num_results').isInt(),
(req, res) => {
// Handle request
},
);
Functions such as oneOf()
and checkExact()
can become slower
when using request-level bail, since validation chains that would normally run in parallel need to
run in sequence.
.if()
if(condition: CustomValidator | ContextRunner): ValidationChain
Adds a condition on whether the validation chain should continue running on a field or not.
The condition may be either a custom validator or a ContextRunner
instance.
body('newPassword')
// Only validate if the old password has been provided
.if((value, { req }) => req.body.oldPassword)
// Or, use a validation chain instead
.if(body('oldPassword').notEmpty())
// The length of the new password will only be checked if `oldPassword` is provided.
.isLength({ min: 6 });
.not()
not(): ValidationChain
Negates the result of the next validator in the chain.
check('weekday').not().isIn(['sunday', 'saturday']);
.optional()
optional(options?: boolean | {
values?: 'undefined' | 'null' | 'falsy',
nullable?: boolean,
checkFalsy?: boolean,
}): ValidationChain
Marks the current validation chain as optional. An optional field skips validation depending on its value, instead of failing it.
Which values are considered optional depends on options.values
.
By default, it's set to undefined
:
options.values | Behavior |
---|---|
undefined | undefined values are optional |
null | undefined and null values are optional |
falsy | Falsy values (empty strings, 0 , false , null and undefined values are optional |
options.nullable
and options.checkFalsy
are deprecated options.
They are aliases to setting options.values
to null
or falsy
.
If options
is false
, then the field won't be optional.
Unlike validators and sanitizers, .optional()
is not positional: it'll affect how values are interpreted,
no matter where it happens in the chain.
For example, there are no differences between this:
body('json_string').isLength({ max: 100 }).isJSON().optional().
and this:
body('json_string').optional().isLength({ max: 100 }).isJSON().
.withMessage()
withMessage(message: any): ValidationChain
Sets the error message used by the previous validator.