3

Using class-validator, validation pipes I would like to mark some fields as required. I tried using @IsNotEmpty method. It throws a 400 error when the input is empty. But i need to throw an error if input is missing as well.

DTO: Address Object with fields address1 and address 2. I would like to have address1 as required and address2 as optional

import {IsString, IsInt, IsNotEmpty } from 'class-validator';
import {ApiModelProperty} from '@nestjs/swagger';
export class Address {

    @ApiModelProperty({description: 'Address Line 1', required : true})
    @IsString()
    @IsNotEmpty()
    required : true
    address1: string;

    @ApiModelProperty({description: 'Address Line 2', required :false})
    @IsString()
    address2?: string;
}
// App.js: Application file where validation pipes are defined.
async function bootstrap() {
    const expressServer = express();

    const app = await NestFactory.create(AppModule, expressServer, {bodyParser: true});
    app.use(bodyParser.json({limit: 6851000}));

    app.useGlobalInterceptors(new UnhandledExceptionInterceptor());

    app.useGlobalFilters(new HttpErrorsExceptionFilter());

    app.useGlobalFilters(new UnhandledExceptionFilter(newLogger('UnhandledExceptionFilter')));

    app.useGlobalPipes(new ValidationPipe({skipMissingProperties: true}));

    app.useGlobalPipes(new ValidationPipe({forbidNonWhitelisted :true, whitelist:true, transform:true}));

}

Sample Input: Sample input with both the fields.

{  
  "shippingAddress": {
    "address1":,
    "address2": null 
  }
}

In this case this provides a 400 as expected, But I also need an error when input is like below missing one of required fields,

{  
  "shippingAddress": {
    "address2": null
   } 
}
0

1 Answer 1

6

This is the standard functionality of class-validator so long as you do not add the @IsOptional() decorator. I'm adding the pipes directly to the controller but the idea is the same. See my class and callouts below:

// test-class.ts
import { IsString, IsOptional } from 'class-validator';

export class TestClass {
  @IsString()
  address1: string;

  @IsString()
  @IsOptional()
  address2?: string;
}
//test-valid.controller.ts
import { Controller, Post, Body, UsePipes, ValidationPipe } from '@nestjs/common';
import { TestClass } from './models/test-class';

@Controller('test-valid')
export class TestValidController {

  @Post()
  @UsePipes(new ValidationPipe({skipMissingProperties: true}))
  @UsePipes(new ValidationPipe({forbidNonWhitelisted: true, whitelist: true, transform: true}))
  async testValidate(@Body() body: TestClass) {
    return 'Valid!';
  }
}

# cURL callouts 
~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid \
> --header "Content-Type: application/json" \
> --data '{"address1": "some address", "address2": "some other address"}'
Valid!

~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid --header "Content-Type: a
pplication/json" --data '{"address2": "some other address"}'
[{"target":{"address2":"some other address"},"property":"address1","children":[],"constraints":{"isString":"address1 must be a string"}}]

~/Documents/gitRepos/nest-testing
$ curl -X POST http://localhost:3000/test-valid --header "Content-Type: a
pplication/json" --data '{"address1": "some address"}'
Valid!

You can see if address1 is missing class-validator will throw an error .

Looking at your code, you have required: true right above your address1: string and not in a decorator, that could be causing an issue of the decorators being applied to the field required instead of address1, just something I thought I'd point out.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.