Serhii
Serhii

Reputation: 7543

Nest.js validate array of strings if there are defined strings only

In the nest.js application on controller level I have to validate DTO.

I've faced with difficulty to check if item is not null (request should be rejected if any list item is null or undefined)

Code bellow demonstrates my configured verifications.

import { ArrayMinSize, IsArray } from 'class-validator'

export class ReminderPayload {
    // ...
    @IsArray()
    @ArrayMinSize(1)
    recipients: string[]
}

Question

  1. I'm looking for help to reject requests with body data like
{
    "recipients": [
        null
    ]
}
  1. How to validate if array items are string only (it should reject handling if object is in the array item position)?

P.S.

'class-validator' injected successfully, and it produces some validation results for my API.

Upvotes: 36

Views: 41104

Answers (2)

HMilbradt
HMilbradt

Reputation: 4639

You need to tell class-validator to run the validations on each item of the array. Change your payload DTO to the following:

import { ArrayMinSize, IsArray, IsString } from 'class-validator';

export class ReminderPayloadDto {
  // ...
  @IsArray()
  @IsString({ each: true })  // "each" tells class-validator to run the validation on each item of the array
  @ArrayMinSize(1)
  recipients: string[];
}

Link to the docs on this.

Upvotes: 73

zemil
zemil

Reputation: 5086

For someone who wants to validate specific strings in array:

class MyDto {
    @IsIn(['monday', 'tuesday', 'wednesday', 'thursday', 'friday'], { each: true })
    weekdays: string[];

    // regex mask validation
    @Matches('^[a-zA-Z\\s]+$', undefined, { each: true })
    words: string[];

    @Contains('hello', { each: true })
    greetings: string[];
}

For custom validation:

import {
  ArrayNotEmpty,
  IsArray,
  Validate,
  ValidateNested,
  ValidatorConstraint,
  ValidatorConstraintInterface
} from 'class-validator'

@ValidatorConstraint({ name: 'arrayPrefixValidator' })
export class ArrayPrefixValidator implements ValidatorConstraintInterface {
  validate(values: string[] = []): boolean {
    if (values.length) {
      return values.every((value) => value.startsWith('user-'))
    }
    return false
  }
}

class MyDto {
    // Each item contains a prefix str-
    @Validate(ArrayPrefixValidator, { message: 'No user- prefix' })
    accounts: string[];
}

For more information go to official docs

Upvotes: 2

Related Questions