I have a pipe
in NestJS to verify that a query param is valid ObjectId
. It takes a string
as input and returns an ObjectId
.
<code>// parse-objectid.pipe.ts
import type { PipeTransform } from '@nestjs/common'
import { Injectable, BadRequestException } from '@nestjs/common'
import { Types } from 'mongoose'
@Injectable()
export class ParseObjectIdPipe implements PipeTransform<string, Types.ObjectId> {
public transform(value: string): Types.ObjectId {
if (!Types.ObjectId.isValid(value)) {
throw new BadRequestException('Validation failed (ObjectId is expected)')
}
return new Types.ObjectId(value)
}
}
</code>
<code>// parse-objectid.pipe.ts
import type { PipeTransform } from '@nestjs/common'
import { Injectable, BadRequestException } from '@nestjs/common'
import { Types } from 'mongoose'
@Injectable()
export class ParseObjectIdPipe implements PipeTransform<string, Types.ObjectId> {
public transform(value: string): Types.ObjectId {
if (!Types.ObjectId.isValid(value)) {
throw new BadRequestException('Validation failed (ObjectId is expected)')
}
return new Types.ObjectId(value)
}
}
</code>
// parse-objectid.pipe.ts
import type { PipeTransform } from '@nestjs/common'
import { Injectable, BadRequestException } from '@nestjs/common'
import { Types } from 'mongoose'
@Injectable()
export class ParseObjectIdPipe implements PipeTransform<string, Types.ObjectId> {
public transform(value: string): Types.ObjectId {
if (!Types.ObjectId.isValid(value)) {
throw new BadRequestException('Validation failed (ObjectId is expected)')
}
return new Types.ObjectId(value)
}
}
The problem is that when I use the pipe in the controller and set the param type to ObjectId
, it gives an error
<code>// book.controller.ts
@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: Types.ObjectId){}
{
"message": [
"an unknown value was passed to the validate function"
],
"error": "Bad Request",
"statusCode": 400
}
</code>
<code>// book.controller.ts
@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: Types.ObjectId){}
{
"message": [
"an unknown value was passed to the validate function"
],
"error": "Bad Request",
"statusCode": 400
}
</code>
// book.controller.ts
@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: Types.ObjectId){}
{
"message": [
"an unknown value was passed to the validate function"
],
"error": "Bad Request",
"statusCode": 400
}
Setting the type to any
or string
works correctly, and inside the controller the authorId
is an ObjectId
.
<code>@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: any){
console.log(typeof authorId) // object
}
</code>
<code>@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: any){
console.log(typeof authorId) // object
}
</code>
@Get('books')
async getBooks(@Query('author_id', ParseObjectIdPipe) authorId: any){
console.log(typeof authorId) // object
}
In main.ts
, I have registered the ValidationPipe
globally as follow:
<code>app.useGlobalPipes(
new ValidationPipe({
forbidNonWhitelisted: true,
forbidUnknownValues: true,
whitelist: true,
transform: true,
stopAtFirstError: true,
transformOptions: {
ignoreDecorators: true
}
})
)
</code>
<code>app.useGlobalPipes(
new ValidationPipe({
forbidNonWhitelisted: true,
forbidUnknownValues: true,
whitelist: true,
transform: true,
stopAtFirstError: true,
transformOptions: {
ignoreDecorators: true
}
})
)
</code>
app.useGlobalPipes(
new ValidationPipe({
forbidNonWhitelisted: true,
forbidUnknownValues: true,
whitelist: true,
transform: true,
stopAtFirstError: true,
transformOptions: {
ignoreDecorators: true
}
})
)