It seems to process request twice if I register ValidationPipe as global and activate 'whitelist' option.
What I tried is to transform boolean data of query parameter using @Transform in class-transformer with @Transform(value => value === 'true' || value === 'True') .
However, it returns always false regardless of what request value is. Therefore, I tried to figure out and now I found that @Transform( ... ) called twice so first time it returns true, and next true === 'true' returns false!
Here is my repository to reproduce issue:
https://github.com/Atanatous/nest-issue-reproduce
// in main.ts
app.useGlobalPipe(new ValidationPipe({ whitelist: true })
// in query.dto.ts
export class QueryDto {
@Transform(value => {
Logger.log(value) // First: true, Second: true
Logger.log(typeof value) // First: 'string', Second: 'boolean'
return value === 'true'
})
bool: boolean
}
@Transform in ValidationPipe should be called only once for each request.
Nest version: > 6.7.2
(my issue reproduce repo is 6.7.2, and my real project is 6.10.14. Both happens.)
For Tooling issues:
- Node version: 10.18.0
- Platform: Mac
Others:
In order to validate your DTO, ValidationPipe has to transform your plain JS object to a class instance (@Transform() is evaluated). Now, since you aren't passing transform: true, the pipe is assuming you want to have a literal object. However, you passed whitelist: true which means that we cannot simply return the value passed to the pipe (because properties won't be whitelisted). Hence, the pipe has to transform it into a plain JS object - serialize it (@Transform() is evaluated once again).
To fix this, you can either:
a) Enable transform: true
b) Set the toClassOnly to true:
@Transform(value => {
return value === 'true';
}, { toClassOnly: true })
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
In order to validate your DTO,
ValidationPipehas to transform your plain JS object to a class instance (@Transform()is evaluated). Now, since you aren't passingtransform: true, the pipe is assuming you want to have a literal object. However, you passedwhitelist: truewhich means that we cannot simply return the value passed to the pipe (because properties won't be whitelisted). Hence, the pipe has to transform it into a plain JS object - serialize it (@Transform()is evaluated once again).To fix this, you can either:
a) Enable
transform: trueb) Set the
toClassOnlytotrue: