nestjs / nest

A progressive Node.js framework for building efficient, scalable, and enterprise-grade server-side applications with TypeScript/JavaScript 🚀
https://nestjs.com
MIT License
66.9k stars 7.55k forks source link

Optional query param / param with default value isn't taken into consideration when using ValidationPipe with transform: true #12864

Closed Hareloo closed 9 months ago

Hareloo commented 9 months ago

Is there an existing issue for this?

Current behavior

I am using a ValidationPipe enabled globally with transform: true.. The problem is that I have query params which are optional, or that should have a default value if not explicitly set, like so:

  async getPatients(
    @Query('limit') limit: number = PAGINATION_DEFAULT_LIMIT,
    @Query('offset') offset: number = 0,

The issue is that both limit and offset get converted to NaN when no value is passed, instead of to the default value I set. If I try to change the code so that these params will be optional like so:

  async getPatients(
    @Query('limit') limit?: number,
    @Query('offset') offset?: number,

The same issue persists...

Minimum reproduction code

https://stackblitz.com/edit/nestjs-typescript-starter-mgxaub?file=src%2Fapp.controller.ts,src%2Fmain.ts

Steps to reproduce

No response

Expected behavior

  1. Create a new project
  2. Install class-validators and class-transform packages
  3. Add global validation pipe with transform
  4. Add an optional query param with number type, call it test
  5. Make a request without test query param and the param will be NaN

Package

Other package

No response

NestJS version

^10.0.0

Packages versions

[Nest Platform Information]
platform-socket.io version : 10.2.10
platform-express version   : 10.2.10
cache-manager version      : 2.1.1
websockets version         : 10.2.10
schematics version         : 10.0.3
passport version           : 10.0.2
schedule version           : 4.0.0
swagger version            : 7.1.16
typeorm version            : 10.0.1
testing version            : 10.2.10
common version             : 10.2.10
config version             : 3.1.1
axios version              : 3.0.1
core version               : 10.2.10
cli version                : 10.2.1

Node.js version

20.10.0

In which operating systems have you tested?

Other

No response

micalevisk commented 9 months ago

how your http request looks like?

Hareloo commented 9 months ago

how your http request looks like?

For example: https://localhost:4001/api/v2/patients Just not specifying the param

kamilmysliwiec commented 9 months ago

Perhaps similarly to boolean parameters, we should skip the primitives transformation when value === undefined?

Hareloo commented 9 months ago

Perhaps similarly to boolean parameters, we should skip the primitives transformation when value === undefined?

I believe something like that would solve this.

kamilmysliwiec commented 9 months ago

Would you like to create a PR for this issue?

Hareloo commented 9 months ago

Would you like to create a PR for this issue?

Sure! I'll get on it soon.

Hareloo commented 9 months ago

Created a PR for this here: https://github.com/nestjs/nest/pull/12893

kamilmysliwiec commented 9 months ago

Let's track this here https://github.com/nestjs/nest/pull/12893

luzhenqian commented 8 months ago

This problem is still not solved yet, my solution is:

  1. Create pipe file:
// pipes/int-default-value-pipe.ts
import { PipeTransform, Injectable, ArgumentMetadata } from '@nestjs/common';

@Injectable()
export class IntDefaultValuePipe implements PipeTransform {
  constructor(private readonly defaultValue: any) {}

  transform(value: string, metadata: ArgumentMetadata): any {
    const val = parseInt(value, 10);
    return isNaN(val) ? this.defaultValue : val;
  }
}
  1. Modify code.

Then put the original code:

@Query('page') page = 0

Change it to this:

@Query('page', new IntDefaultValuePipe(0)) page

It working.

stouch commented 5 months ago

No solution for this ?

We encounter this problem too . When we use :

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

..it corrupts our @Query default param values to NaN.

We would like to keep the clean writing: @Query('page') page = 0 for our query parameters so we dont use the @luzhenqian's solution.