Search code examples
angularhttpgethttprequest

Number Turns to String over Http Request from Angular Client to NestJS Server


Number Turns to String over Http Request from Angular Client to NestJS Server:

I pass firstIndex: number through the params of a GET http request from my Angular client to my NestJS server. Everywhere I define it as a number. In the params of my service function firstIndex: number. When grabbing it from the server side @Query('firstIndex') firstIndex: number But when I try to use it, I run into problems. When I log the typeof firstIndex it comes out as a string. I have to convert it to a number using const firstInd = Number(firstIndex).

I'm assuming this is just something to do with the nature of http requests themselves, but I'm intrigued to know the speicific reason.


Solution

  • I had a similar issue when I was getting started with NestJS and routes.

    Then, while going through the documentation and some open source NestJS API projects, I found multiple ways to tackle this issue.

    1. You can utilize ValidationPipe to automatically transform the payload to your desired type.

    There are two ways to do it.

    The first one is to apply the ValidationPipe at your controller method level.

    @Get()
    @UsePipes(new ValidationPipe({ transform: true })) // <--- Add this line
    getRows(
      @Query('firstIndex') firstIndex: number,
      @Query('limit') limit: number,
      @Query('sorts') sorts: string
    ){
      console.log(typeof firstIndex === 'number'); // true
      console.log(typeof limit === 'number'); // true
      console.log(typeof sorts === 'string'); // true
    }
    

    The other way to apply the ValidationPipe behavior at global level.

    This is how you would do it in your NestJS App instantiate file:

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

    (ValidationPipe and @UsePipes() decorator are imported from the @nestjs/common package)

    You can read more about this in NestJS Transform payload objects doc.

    1. The second way is to explicit convert the type of the value.

    This is how you can get it done:

    @Get()
    getRows(
      @Query('firstIndex', ParseIntPipe) firstIndex: number, // <-- Added ParseIntPipe
      @Query('limit', ParseIntPipe) limit: number, // <-- Added ParseIntPipe
      @Query('sorts') sorts: string
    ){
      console.log(typeof firstIndex === 'number'); // true
      console.log(typeof limit === 'number'); // true
      console.log(typeof sorts === 'string'); // true
    }
    

    (The ParseIntPipe is imported from the @nestjs/common package)

    As you can see, here, I have passed another parameter which is a Pipe in the @Query decorator. It will parse the value as an integer.

    You can read more about NestJS Transform Explicit conversion doc here.

    External Links: