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.89k stars 7.56k forks source link

@Pipe don't transform the value when is used in WebSockets #313

Closed Caballerog closed 6 years ago

Caballerog commented 6 years ago

I'm submitting a...


[ ] Regression 
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

The @pipe are not transform the value return from the pipe when you're using websockets.

The following code are not works (very simple example and useless). import { WsException } from '@nestjs/websockets'; import { Pipe, PipeTransform, ArgumentMetadata } from '@nestjs/common';

@Pipe()
export class ExamplePipe implements PipeTransform<string> {
  public async transform(value: string, metadata: ArgumentMetadata) {
    console.log("value", value);
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new WsException('Validation failed');
    }
    console.log(typeof val);
    console.log(val);
    return 4; <- Should return the value 4 (like integer)
  }
}
@UsePipes(new FakePipe())
  onEvent(client, data: string): Observable<WsResponse<number>> {
    console.log(data); // any string
    const userID = data.userID;
    if (userID === -1) {
      throw new WsException('Invalid credentials.');
    } else {
      console.log("DATA IS NOT -1", data);
    }
  //Other code
  }

The data never is transform from the @pipe

Expected behavior

The data should be transformed just as it happens with pipes in HTTP

Minimal reproduction of the problem with instructions

Only copy the FakePipe in your code, and you see the error (the parseIntPipe are not exists in Websockets module).

What is the motivation / use case for changing the behavior?

I'm not sure

Environment

Nest 4.4


Nest version: X.Y.Z


For Tooling issues:
- Node version:  7.8.0
- Platform:  Mac :-( (I wish any day come back to Linux....)

Others:

cojack commented 6 years ago

I can confirm that.

From nest examples 02-gateways, I have modify the events.gateway.ts

import { WebSocketGateway, SubscribeMessage, WsResponse, WebSocketServer, WsException } from '@nestjs/websockets';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/from';
import 'rxjs/add/operator/map';
import {UsePipes} from '@nestjs/common';
import {ParseIntPipe} from '../common/pipes/parse-int.pipe';

@WebSocketGateway()
export class EventsGateway {
  @WebSocketServer() server;

  @SubscribeMessage('events')
  @UsePipes(new ParseIntPipe())
  onEvent(client, data): Observable<WsResponse<number>> {
    const event = 'events';
    const response = [1, 2, 3];

    return Observable.from(response)
      .map((res) => ({ event, data: res }));
  }
}

Added new parse-int.pipe.ts as:

import { HttpException } from '@nestjs/core';
import { PipeTransform, Pipe, ArgumentMetadata, HttpStatus } from '@nestjs/common';

@Pipe()
export class ParseIntPipe implements PipeTransform<string> {
    async transform(data: any, metadata: ArgumentMetadata) {
        const val = parseInt(data.value, 10);
        if (isNaN(val)) {
            throw new HttpException('Validation failed', HttpStatus.BAD_REQUEST);
        }
        return val;
    }
}

and data in onEvent function is still object with value key as string "2", this is what I send through socket:

            socket.on('connect', function() {
                console.log('Connected');
                socket.emit('events', { value: "2" });
            });

But modification on the reference works, so, if you change the pipe transformation to something like this:

import { HttpException } from '@nestjs/core';
import { PipeTransform, Pipe, ArgumentMetadata, HttpStatus } from '@nestjs/common';

@Pipe()
export class ParseIntPipe implements PipeTransform<string> {
    async transform(data: any, metadata: ArgumentMetadata) {
        data.value = parseInt(data.value, 10);
        if (isNaN(data.value)) {
            throw new HttpException('Validation failed', HttpStatus.BAD_REQUEST);
        }
        return data;
    }
}

the data.value inside onEvent function will have number: 2. But however this behaviour is at least strange.

kamilmysliwiec commented 6 years ago

Hi @Caballerog, As far as I remember this issue is fixed since 4.5.0. Could you verify this?

Caballerog commented 6 years ago

Hi @kamilmysliwiec,

I just to test the code using 4.5.0, and this works perfectly.

Thanks!

lock[bot] commented 4 years ago

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.