Custom pipes let you change or check data before your code uses it. They help keep your app clean and safe.
Custom pipes in NestJS
import { PipeTransform, Injectable, ArgumentMetadata, BadRequestException } from '@nestjs/common'; @Injectable() export class CustomPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { // change or check value here return value; // return changed or original value } }
The transform method runs automatically on data.
Throw BadRequestException to stop bad data.
import { PipeTransform, BadRequestException } from '@nestjs/common'; export class ParseIntPipe implements PipeTransform { transform(value: any) { const val = parseInt(value, 10); if (isNaN(val)) { throw new BadRequestException('Value must be a number'); } return val; } }
import { PipeTransform } from '@nestjs/common'; export class TrimPipe implements PipeTransform { transform(value: any) { if (typeof value === 'string') { return value.trim(); } return value; } }
This example shows a controller with a custom pipe that changes the query parameter id from a string to a number. If id is not a number, it stops the request with an error.
import { Controller, Get, Query, UsePipes, PipeTransform, Injectable, BadRequestException } from '@nestjs/common'; @Injectable() class ParseIntPipe implements PipeTransform { transform(value: any) { const val = parseInt(value, 10); if (isNaN(val)) { throw new BadRequestException('Value must be a number'); } return val; } } @Controller('items') export class ItemsController { @Get() @UsePipes(new ParseIntPipe()) getItem(@Query('id') id: number) { return `Item id is ${id}`; } }
Always add @Injectable() to your custom pipe class.
Use pipes to keep your controller code clean and focused on business logic.
You can apply pipes globally, to controllers, or to specific routes.
Custom pipes let you check or change data before your code uses it.
They help catch errors early and keep your app safe.
You write a class with a transform method to make a custom pipe.
Practice
What is the main purpose of a custom pipe in NestJS?
Solution
Step 1: Understand the role of pipes in NestJS
Pipes are used to transform or validate incoming data before it reaches the controller methods.Step 2: Identify what custom pipes specifically do
Custom pipes allow developers to create their own logic for data transformation or validation to ensure data safety and correctness.Final Answer:
To transform or validate data before it reaches the route handler -> Option AQuick Check:
Custom pipes = data validation/transformation [OK]
- Confusing pipes with middleware
- Thinking pipes handle database or session logic
- Assuming pipes style frontend components
Which of the following is the correct way to define a custom pipe class in NestJS?
export class MyPipe implements PipeTransform {
transform(value: any, metadata: ArgumentMetadata) {
// logic here
}
}Solution
Step 1: Recall the PipeTransform interface signature
The transform method must accept two parameters: value and metadata of type ArgumentMetadata.Step 2: Check which option matches the correct method signature
export class MyPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { } } correctly implements the transform method with both parameters and the class implements PipeTransform.Final Answer:
export class MyPipe implements PipeTransform { transform(value: any, metadata: ArgumentMetadata) { } } -> Option BQuick Check:
transform(value, metadata) = correct signature [OK]
- Omitting the metadata parameter
- Using a function instead of a class
- Not implementing PipeTransform interface
Given this custom pipe code, what will be the output if the input value is "123"?
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common';
@Injectable()
export class ParseIntPipe implements PipeTransform {
transform(value: any) {
const val = parseInt(value, 10);
if (isNaN(val)) {
throw new BadRequestException('Validation failed');
}
return val;
}
}Input: "123"
Solution
Step 1: Understand parseInt behavior on string "123"
parseInt("123", 10) converts the string "123" to the number 123.Step 2: Check the validation condition
Since 123 is a valid number, isNaN(val) is false, so no exception is thrown and the number 123 is returned.Final Answer:
Returns number 123 -> Option DQuick Check:
parseInt("123") = 123 [OK]
- Thinking it returns string instead of number
- Assuming it throws error for numeric strings
- Confusing NaN with valid number
Identify the error in this custom pipe code:
import { PipeTransform, Injectable } from '@nestjs/common';
@Injectable()
export class UppercasePipe implements PipeTransform {
transform(value: string) {
return value.toUpperCase;
}
}Solution
Step 1: Check the transform method implementation
The method returns value.toUpperCase without parentheses, which is a reference to the function, not the result.Step 2: Identify correct usage of toUpperCase
toUpperCase is a method and must be called with parentheses: value.toUpperCase()Final Answer:
toUpperCase is used without parentheses -> Option CQuick Check:
Method calls need () to execute [OK]
- Forgetting parentheses on method calls
- Assuming decorators are missing when present
- Ignoring interface implementation
You want to create a custom pipe that trims whitespace and converts input to lowercase. Which of these implementations correctly achieves this?
import { PipeTransform, Injectable } from '@nestjs/common';
@Injectable()
export class NormalizePipe implements PipeTransform {
transform(value: any) {
// Which option is correct?
}
}Solution
Step 1: Understand method chaining order
trim() removes whitespace from start and end, then toLowerCase() converts to lowercase. The order matters to avoid errors.Step 2: Check method call syntax
Both trim() and toLowerCase() are methods and must be called with parentheses. return value.trim().toLowerCase(); correctly calls them in order: value.trim().toLowerCase()Final Answer:
return value.trim().toLowerCase(); -> Option AQuick Check:
Correct method chaining with () = return value.trim().toLowerCase(); [OK]
- Calling methods without parentheses
- Wrong method chaining order
- Using properties instead of methods
Ready to prove it?
Pass the test and this pattern moves unknown
