You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
4 Hrs
48 Min
50 Seg

Crea tu propio pipe

18/23
Resources

Creating your own data validations will be very important to secure your application and avoid unexpected errors.

How to create custom PIPES

Create your own PIPE to implement custom data validation logic.

1. Create your first Pipe

With the NestJS CLI auto-generate a new pipe with the command nest generate pipe <pipe-name> or in its short form nest g p <pipe-name>.
By default, you will see code like the following.

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'; @Injectable()export class ParseIntPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { return value; } } }

2. Implement the Pipe logic

Implement your own data transformation and validation logic here. Note that if the data is invalid, you can throw exceptions to inform the front-end that the data is wrong.

import { ArgumentMetadata, Injectable, PipeTransform, BadRequestException } from '@nestjs/common'; @Injectable()export class ParseIntPipe implements PipeTransform { transform(value: string, metadata: ArgumentMetadata) { const finalValue = parseInt(value, 10); if (isNaN(finalValue)) { throw new BadRequestException(`${value} is not a number.`); } return finalValue; } }

3. Import and use the Pipe

Finally, implement your custom PIPE in the driver.

import { ParseIntPipe } from './pipes/parse-int.pipe'; @Get('product/:idProduct') getProduct(@Param('idProduct', ParseIntPipe) idProduct: string): string { // ...}

You can develop the logic to validate and transform the data that best suits your needs. It is fundamental not to allow the input of erroneous data to your controllers. For that reason, the pipes are a previous layer to the controllers to make this validation.

Generate a pipe with nest g pi common/parse-int

// src/common/parse-int.pipe.tsimport { ArgumentMetadata, Injectable, PipeTransform, BadRequestException, } from '@nestjs/common'; @Injectable()export class ParseIntPipe implements PipeTransform { transform(value: string, metadata: ArgumentMetadata) { const val = parseInt(value, 10); if (isNaN(val)) { throw new BadRequestException(`${value} is not an number`); } return val; } } }

Contributed by: Kevin Fiorentino.

Contributions 25

Questions 9

Sort by:

Want to see more contributions, questions and answers from the community?

Puedes crear tus propios pipes para crear validaciones y transformaciones personalizadas.

nestjs se trae la esencia de angular, es una maravilla!

También puedes usar el objeto Number(), para parsear la string numérica, con este objeto también evitas que parseInt te haga el parse cuando envías un número con letras.
Number()

Una curiosidad de parseInt(), que descubri probando (tal vez muchos ya la sepan, pero para mi es nuevo), es que si (en el argumento) tienes un string empezando por un numero y luego un caracter alfanumerico, devuelve el numero antes del primer caracter no numerico.
Ej.: si tienes

parseInt('12yletras')
devuelve --> 12

Bueno espero les sirva, saludos!
PD.: Me esta gustando mucho el curso hasta ahora! 👍️

Los pipes tienen dos funciones principales validar y transformar.

Importarlo

import { ParseIntPipe, } from '@nestjs/common';

Implementarlo

@Get(':productId')
@HttpCode(HttpStatus.ACCEPTED)
getProduct(@Param('productId', ParseIntPipe) productId: number) {
  return this.productService.findOne(productId);
}

Custom pipes

Tambien se puede crear un pipe customizable:

  • Con el comando: nest g pipe common/parse-int
CREATE src/common/parse-int.pipe.spec.ts (173 bytes)
CREATE src/common/parse-int.pipe.ts (224 bytes)
  • Crea el siguiente codigo del pipe
import { ArgumentMetadata, Injectable,PipeTransform, } from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform {
  transform(value: string, metadata: ArgumentMetadata) {
    return value;
  }
}
  • reescribiendo el parseInt:
import {
  ArgumentMetadata,
  Injectable,
  PipeTransform,
  BadRequestException,
} from '@nestjs/common';

@Injectable()
export class ParseIntPipe implements PipeTransform {
  transform(value: string, metadata: ArgumentMetadata) {
    const val = parseInt(value, 10);
    if (isNaN(val)) {
      throw new BadRequestException(`${value} is not number`);
    }
    return val;
  }
}

Pipes que tiene nestjs https://github.com/nestjs/nest/tree/master/packages/common/pipes

Agregue una validacion extra para el parseintpipe por que cuando ingresaba numeros con una letra o muchas letras no me lograba atrapar el error.
 
Este es mi codigo:

  transform(value: string, metadata: ArgumentMetadata) {
    const val = parseInt(value, 10);

    if (isNaN(val) || /\D/.test(value)) {
      throw new BadRequestException(`${value} is not a number.`);
    }

    return val;
  }

con el comando de la clase para el pipe se crea una subcarpeta, por lo que el import sería:

import { ParseIntPipe } from '../common/parse-int/parse-int.pipe';
 
¿ID entero o ID alfanumérico? La decisión de manejar la validación de diferentes tipos de ID (como enteros para SQL o cadenas alfanuméricas para MongoDB) dentro de un mismo Pipe o en Pipes separados depende del diseño de tu aplicación, la claridad del código y el principio de responsabilidad única (Single Responsibility Principle - SRP) ```js @Injectable() export class ValidateIdPipe implements PipeTransform { transform(value: string, metadata: ArgumentMetadata) { const isMongoId = /^[a-fA-F0-9]{24}$/.test(value); // Valida formato de ObjectId de MongoDB const isInt = /^[0-9]+$/.test(value); // Valida números enteros if (!isMongoId && !isInt) { throw new BadRequestException( `${value} no es un ID válido. Debe ser un número entero o un ObjectId.`, ); } return isInt ? parseInt(value, 10) : value; // Devuelve el número entero o la cadena alfanumérica } ```**Recomendación práctica** Para proyectos con arquitecturas grandes o en crecimiento, suele ser mejor separar los Pipes por tipo de ID. Esto mejora la escalabilidad y el mantenimiento del código. Sin embargo, si manejas ambos tipos de ID en un único endpoint y deseas simplicidad, un Pipe unificado puede ser una solución adecuada.
`export class ParseIntegerIdPipe implements PipeTransform {` ` transform(value: any, metadata: ArgumentMetadata) {` ` const reg = /^\d+$/;` ` if (!reg.test(value)) {` ` throw new BadRequestException('Is not an integer');` ` }` ` return parseInt(value, 10);` ` }` `}`
puedes utilizar `npx` para ejecutar el comando `nest` sin la necesidad de instalarlo globalmente. Aquí está el comando que puedes utilizar para generar el pipe: `npx @nestjs/cli generate pipe common/parse-int`

Le pregunte a chatgpt como se testea ese pipe y me arrojo esto

import { ArgumentMetadata, BadRequestException } from '@nestjs/common';
import { ParseIntPipe } from './parse-int.pipe';

describe('ParseIntPipe', () => {
  let pipe: ParseIntPipe;

  beforeEach(() => {
    pipe = new ParseIntPipe();
  });

  it('should be defined', () => {
    expect(pipe).toBeDefined();
  });

  it('should transform a valid numeric string into an integer', () => {
    const value = '42';
    const metadata = {} as ArgumentMetadata;
    const expectedOutput = 42;
    const result = pipe.transform(value, metadata);

    expect(result).toEqual(expectedOutput);
  });

  it('should throw a BadRequestException for an invalid numeric string', () => {
    const value = 'invalid';
    const metadata = {} as ArgumentMetadata;

    expect(() => {
      pipe.transform(value, metadata);
    }).toThrow(BadRequestException);
  });
});

Si queremos usar pipes con parametros o queries que son opcionales, podemos aplicar algo como esto:

products.controller.ts

  @Get()
  getProducts(
    @Query('limit', new ParseIntPipe(false)) limit = 100,
    @Query('offset', new ParseIntPipe(false)) offset = 0,
    @Query('brand') brand: string,
  ) {
    return this.productsService.findAll();
  }

parse-int.pipe.ts

@Injectable()
export class ParseIntPipe implements PipeTransform {
  constructor(private isRequired: boolean) {}

  transform(value: string, metadata: ArgumentMetadata) {
    const val = Number(value);
    if (isNaN(val) && this.isRequired) {
      throw new BadRequestException(
        `Validation failed. ${value} is not a number`,
      );
    }
    return val;
  }
}

import { ArgumentMetadata, Injectable, PipeTransform, BadRequestException } from ‘@nestjs/common’;

@Injectable()
export class ParseIntPipe implements PipeTransform {

transform(value: string, metadata: ArgumentMetadata) {
const finalValue = parseInt(value, 10);
if (isNaN(finalValue)) {
throw new BadRequestException(${value} 👀 Tiene que ser de tipo numero el /id.);
}
return finalValue;
}
}

ame este curso

Tambien es posible pasar varios Pipes, de esta manera

ya me dieron ganas de aprender angular

me pareció muy llamativa la validación que Nest hace para saber si es numérico un valor.

Se parece a los pipes de angular

Crea tu propio Pipe

Puedes crear tus propios pipes para crear validaciones y transformaciones personalizadas.

Desde la terminal ejecutamos el siguiente comando:

nest g pipe common/parse-int

Nos creara dentro de la carpeta common dos archivos unos para el desarrollo de nuestro pipe y otro para la pruebas correspondientes

Dentro del archivo parse-int.pipe.ts vamos a desarrollar un pipe para convertir de string a number:

export class ParseIntPipe implements PipeTransform {
  transform(value: string, metadata: ArgumentMetadata) {
		const val = parseInt(value, 10);
		if(isNaN(val)){
			throw new BadRequestException(`El valor is not an number`)
		}
    return val;
  }
}

luego simplemente lo importamos en nuestro controlador y hacemos uso del pipe:

import { ParseIntPipe } from './../../common/parse-int.pipe'

@Get(':productId')
	@HttpCode(HttpStatus.ACCEPTED)
	getOne(@Param('productId', ParseIntPipe) productId: number) {
		return this.productsService.findOne(productId);
	}

es como Angular pero para el Backend!

Revisar el repositorio de Nest Js directamente en la carpeta Common puedes visualizar todos los PIPES ya pre-construidos por defecto.

Utilizar el PIPE que creamos para validar y transformar

Lanzar excepcion BadRequestException cuando no es posible transformar el dato al tipo correcto

Generar un nuevo PIPE (Validar y Transformar) desde el CLI

nest generate pipe common/parse-int -flat

👏