Search code examples
javascripttypescriptclass-validator

Class validator allow when undefined but not when null


  @IsOptional()
  @Transform(({ value }) => (value ? new Date(value) : null))
  @IsDate()
  doj: Date;

The above code works fine when doj is undefined. It has the same behavior when doj is also null.

However, I want the validation to pass when it is undefined and fail if null. How do I achieve this with class validator?

EDIT:

Based on the accepted answer, I made a function to validate and transform dates. This is for nestjs with graphql btw.

import { BadRequestException } from '@nestjs/common';
import { TransformFnParams } from 'class-transformer';
import * as moment from 'moment';

export const dateTransformValidate = (
  params: TransformFnParams & { nullable: boolean }
) => {
  const date = params.value;
  if (date == null) {
    if (params.nullable === false) {
      throw new BadRequestException(`Cannot remove ${params.key}.`);
    }
    return date;
  }
  const m = moment(date);
  if (m.isValid()) return date;
  throw new BadRequestException('Invalid date.');
};

Usage:

// allow undefined but not nulls
  @Field({ nullable: true })
  @IsOptional()
  @Transform((params) => dateTransformValidate({ ...params, nullable: false }))
  dob: Date;

// allow undefined and null
  @Field({ nullable: true })
  @IsOptional()
  @Transform(dateTransformValidate)
  doj: Date;

Solution

  • Just check out if doj is null and throw an Error

    import { IsOptional, IsDate } from 'class-validator';
    import { Transform, TransformFnParams, plainToClass } from 'class-transformer';
    
    function transformFn(params: TransformFnParams) {
        if (params.value == null) {
            throw new Error('value cannot be null')
        }
        return new Date(params.value)
    }
    class MyClass {
        @IsOptional()
        @Transform(transformFn) 
        @IsDate()
        doj: Date | undefined;    
    }
    
    //tests
    let instance = plainToClass(MyClass, JSON.parse('{"doj": "2022-02-08T12:00:00Z"}'));
    console.log(instance.doj, typeof instance.doj); //2022-02-08T12:00:00Z object
    
    instance = plainToClass(MyClass, JSON.parse('{}'));
    console.log(instance.doj); //undefined
    
    instance = plainToClass(MyClass, JSON.parse('{"doj": null}'));
    console.log(typeof instance.doj); //Error: 'value cannot be null'
    

    Sandbox