Boolean in swagger sent as string instead of boolean in NestJS

Viewed 2575

I'm not understanding why Swagger is sending my boolean value as a string and not as a boolean.

I have set the value of the field as a boolean in the Dto.

It's working with Postman sending a boolean but not with Swagger which is sending as a string...

Here is my controller using the CreateIssueDto

/**
   * Create an issue
   * @param image
   * @param issue
   */
  @ApiBearerAuth()
  @ApiOperation({ description: 'Create an issue' })
  @UseInterceptors(FileInterceptor('image'))
  @ApiConsumes('multipart/form-data')
  @Roles(Role.HeadOfPole, Role.Corrector, Role.Editor)
  @Post('create')
  createIssue(@UploadedFile() image, @Body() issue: CreateIssueDto) {
    image ? (issue.image = image.path) : null;
    return this.issuesService.createIssue(issue);
  }

Here is my CreateIssueDto with Swagger decorators

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { IsNotEmpty } from 'class-validator';

export class CreateIssueDto {
  @ApiProperty()
  @IsNotEmpty()
  userId: number;

  @ApiProperty()
  @IsNotEmpty()
  description: string;

  @ApiPropertyOptional()
  isCritical: boolean;

  @ApiPropertyOptional({ type: 'string', format: 'binary' })
  image: string;
}

I added two logs to print the difference in the controller

console.log(issue);
console.log(issue.isCritical, typeof issue.isCritical);

So here is the object and the type of isCritial using Swagger

[Object: null prototype] {
  userId: '1',
  description: 'There is a problem',
  isCritical: 'true'
}
true string

And here is the object and the type of isCritial using Postman

{ userId: 1, description: 'There is a problem', isCritical: true }
true boolean
2 Answers

Use Transform function from 'class-transformer' to fix it, there are two approaches:

First one, transform the value directly in the dto file:

@Transform(value => {
  return value === 'true' || value === true || value === 1 || value === '1'
})
isCritical: boolean;

The second approaches, which highly recommended, export a ToBoolean function under the decorators repository, and use it everywhere:

 export function ToBoolean(): (target: any, key: string) => void {
    return Transform((value: any) => value === 'true' || value === true || value === 1 || value === '1');
}

CreateIssueDto file:

export class CreateIssueDto {
  ///
  @ApiPropertyOptional()
  @ToBoolean()
  isCritical: boolean;
  ///

maybe because in file main.ts of your project you have enableImplicitConversion in true, you need change that variable to false and with this change variables sent by postman doesn't change the type.

This change works for me, I hope it will useful for you

enter image description here

Related