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
67.73k stars 7.63k 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 11 months ago

Hareloo commented 11 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 11 months ago

how your http request looks like?

Hareloo commented 11 months ago

how your http request looks like?

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

kamilmysliwiec commented 11 months ago

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

Hareloo commented 11 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 11 months ago

Would you like to create a PR for this issue?

Hareloo commented 11 months ago

Would you like to create a PR for this issue?

Sure! I'll get on it soon.

Hareloo commented 11 months ago

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

kamilmysliwiec commented 11 months ago

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

luzhenqian commented 10 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 7 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.