I've started to play with NestJS and TypeScript.
I made a simple application that returns the user from MongoDB by ID on a GET request. And the response to client should not have some fields such as password
But if i use .lean() i get response with _id === {}:
{
"_id": {},
"firstName": "sdfsdf",
"lastName": "dfgdfg5y",
"time": 234234
}
If I don't use the lean(), I get mongoose model object:
{
"$__": {
"activePaths": {
"paths": {
"_id": "init",
"firstName": "init",
"lastName": "init",
"password": "init",
"time": "init"
},
"states": {
"ignore": {},
"default": {},
"init": {
"_id": true,
"firstName": true,
"lastName": true,
"password": true,
"time": true
},
"modify": {},
"require": {}
},
"stateNames": [
"require",
"modify",
"init",
"default",
"ignore"
]
},
"strictMode": true,
"skipId": true,
"selected": {},
"fields": {},
"exclude": null,
"_id": {}
},
"$isNew": false,
"_doc": {
"_id": {},
"firstName": "sdfsdf",
"lastName": "dfgdfg5y",
"password": "some pass",
"time": 234234
}
}
Iterestingly, the console.log() in the user.controller.ts prints the object I need to the console:
{
_id: new ObjectId("6245e409e06ac89e5f03851b"),
firstName: 'sdfsdf',
lastName: 'dfgdfg5y',
password: 'some pass',
time: 234234
}
I expect to get an object with _id and an excluded password
user.module.ts
import { User, UserSchema } from './schemas/user.schema';
import { MongooseModule } from '@nestjs/mongoose';
import { UserService } from './user.service';
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
@Module({
imports: [MongooseModule.forFeature([{ name: User.name, schema: UserSchema }])],
controllers: [UserController],
providers: [UserService]
})
export class UserModule {}
user.controller.ts
import { UserService } from './user.service';
import { UserDto } from './dto/user.dto';
import { ClassSerializerInterceptor, Controller, UseInterceptors, Get, Param } from '@nestjs/common';
@Controller('user')
@UseInterceptors(ClassSerializerInterceptor)
export class UserController {
constructor(private readonly service: UserService) {}
@Get('/:id')
async getOne(@Param('id') id: string): Promise<UserDto> {
const user = await this.service.findOne(id);
console.log(user); // <===============================================
return new UserDto(user);
}
}
user.service.ts
import { UserDto } from './dto/user.dto';
import { User, UserDocument } from './schemas/user.schema';
import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
@Injectable()
export class UserService {
constructor(@InjectModel(User.name) private UserModel: Model<UserDocument>) {}
async findOne(id: string): Promise<UserDto> {
return await this.UserModel.findById(id).lean();
}
}
user.dto.ts
import { Exclude, Expose } from 'class-transformer';
export class UserDto {
@Expose()
_id: string;
firstName: string;
lastName: string;
time: number;
@Exclude()
password: string;
constructor(partial: Partial<UserDto>) {
Object.assign(this, partial);
}
}
user.schema.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type UserDocument = User & Document;
@Schema()
export class User {
@Prop()
firstName: string;
@Prop()
lastName: string;
@Prop()
password: string;
@Prop()
time: number;
}
export const UserSchema = SchemaFactory.createForClass(User);