class-tranformer's "Exclude" decorator not Excluding property in NestJS

Viewed 1084

I tried to exclude a property within an entity in NestJS but unfortunately it doesn't seem to be excluding it, when I make a request, it includes the property

Code:

// src/tasks/task.entity.ts
import { Exclude } from 'class-transformer';
import { User } from 'src/auth/user.entity';
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { TaskStatus } from './task-status.enum';

@Entity()
export class Task {
  @PrimaryGeneratedColumn('uuid') id?: string;

  @Column() title: string;

  @Column() description: string;

  @Column() status: TaskStatus;

  @Exclude({ toPlainOnly: true }) // -> not working
  @ManyToOne((_) => User, (user) => user.tasks, { eager: false })
  user: User;
}

src/transform.interceptor.ts

import {
  NestInterceptor,
  Injectable,
  CallHandler,
} from '@nestjs/common';
import { classToPlain } from 'class-transformer';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(_: any, next: CallHandler<any>) {
    return next.handle().pipe(map((data) => classToPlain(data)));
  }
}

src/task.service.ts (relevant methods)

@Injectable()
export class TasksService {
  constructor(@InjectRepository(TaskRepo) private tasksRepo: TaskRepo) {}

// ...
  createTask(createTaskDto: CreateTaskDto, user: User) {
    return this.tasksRepo.createTask(createTaskDto, user);
  }

// ...
}

src/tasks.controller.ts

@Controller('tasks')
@UseGuards(AuthGuard())
export class TasksController {
  constructor(private tasksService: TasksService) {}

  @Post()
  createTask(@Body() createTaskDto: CreateTaskDto, @GetUser() user: User) {
    return this.tasksService.createTask(createTaskDto, user);
  }
// ...
}

// src/main.ts
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { TransformInterceptor } from './transform.interceptor';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  app.useGlobalInterceptors(new TransformInterceptor());
  await app.listen(3030).catch(console.error);
}
bootstrap().catch(console.error);

main.ts file after @omidh's answer, unfortunately doesn't seem to work

import { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common';
import { NestFactory, Reflector } from '@nestjs/core';
import { AppModule } from './app.module';
import { TransformInterceptor } from './transform.interceptor';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe());
  app.useGlobalInterceptors(new TransformInterceptor());
  app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));
  await app.listen(3030).catch(console.error);
}
bootstrap().catch(console.error);

Is there something I'm doing wrong here?

2 Answers

you need class serializer interceptor, Try this in your main file:

    app.useGlobalInterceptors(new ClassSerializerInterceptor(app.get(Reflector)));

If your goal is only to return plain object of an entity, then you can ditch all the code relating to transformer and instead declare a method inside the entity:

toJSON() {
   return classToPlain(this)
}

This will automatically convert your entity classes into plain objects.

Related