Discover how to clean up your code and avoid bugs by automating input checks with custom pipes!
Why Custom pipes in NestJS? - Purpose & Use Cases
Imagine you have to check and transform every input value manually in each controller method before using it.
You write repetitive code to validate and convert data everywhere.
Manual validation and transformation is repetitive, error-prone, and clutters your controller logic.
It's easy to forget checks or apply inconsistent rules, leading to bugs and security risks.
Custom pipes let you centralize validation and transformation logic in reusable classes.
They automatically run before your controller methods, keeping your code clean and consistent.
const id = parseInt(req.params.id); if (isNaN(id)) throw new Error('Invalid ID'); // use id
@UsePipes(new ParseIntPipe()) @Get(':id') getById(@Param('id') id: number) { /* use id directly */ }
You can easily enforce rules and transform inputs across your app without repeating code.
Validating user IDs or query parameters to ensure they are numbers before processing requests.
Manual input checks clutter code and cause bugs.
Custom pipes centralize validation and transformation.
They keep controllers clean and consistent.
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
