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
.