Home > Mobile >  Cannot cast boolean query parameter to actual boolean value Nest.js
Cannot cast boolean query parameter to actual boolean value Nest.js

Time:08-29

In my API I have created endpoint that allows to get users from database with pagination:

@Get()
findByQuery(
  @Query() { skip, take, count }: QueryDto
): Promise<User[] | { rows: User[]; count: number }> {
  return this.userService.findByQuery(skip, take, count);
}

In QueryDto using class-validator I've made validator for values and using class-transformer parser for those values, cause, from query, by default, they are just strings.

import { Transform } from 'class-transformer';
import { IsBoolean, IsNumber, IsOptional } from 'class-validator';

export class QueryDto {
  @Transform(({ value }) => parseInt(value))
  @IsNumber()
  skip: number;

  @Transform(({ value }) => parseInt(value))
  @IsNumber()
  take: number;

  @Transform(({ value }) => {
    return value === 'true';
  })
  @IsOptional()
  @IsBoolean()
  count?: boolean;
}

And here is the problem, this last validator for count field just doesn't work. In service it's still just string.

So, for example, if I do request like this - http://localhost:3000/api/user?skip=1&take=1&count=false - fields skip and take are parsed to numbers correctly, but count is always string.

How can I fix this?

PS.

Also, I have created custom validation pipe, and I am now sure, if problem can be here:

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import { validate } from 'class-validator';
import { ValidationException } from '../exception/validation.exception';

@Injectable()
export class ValidationPipe implements PipeTransform<any> {
  async transform(value: any, metadata: ArgumentMetadata): Promise<any> {
    const obj = plainToInstance(metadata.metatype, value);
    const errors = await validate(obj);

    if (errors.length) {
      const messages = errors.map((err) => {
        return {
          [err.property]: `${Object.values(err.constraints).join(', ')}`
        };
      });
      throw new ValidationException({ errors: messages });
    }
    return value;
  }
}

CodePudding user response:

Your custom pipe should return obj. value is the orginal query. I tested your code. Fields skip and take are both strings. Finally, it is recommended to use the built-in ValidationPipe.

  • Related