6
votes

I want to create functionality where I can transform incoming data before it hits the database. Let's say that we want to make sure that when a new user is created, the firstName and lastName attribute values are always starting with a capital letter. Or another great example is to prevent login issues and store email addresses always in lowercase letters.

I've taken a look at the pipe documentation of NestJS but it's too generic. I want to be able to specify which fields need transformation and I don't want to create a pipe for each attribute or endpoint that needs transformation.

I've also tried the @Transform decorator form the 'class-transformer' package but this doesn't seem to work.

export class UserRoleCreateDto {
  @IsDefined()
  @IsString()
  @IsNotEmpty()
  @Transform((name) => name.toUpperCase())
  readonly name;
}

The expected result should be the name in uppercase letters but it's not.

Anyone any ideas or examples on how to implement proper input transformation for NestJS / TypeORM before it hits the database?

Thanks for your time!

2

2 Answers

11
votes

Here is a small working example

  @UsePipes(new ValidationPipe({transform: true}))
  @Get('test_input')
  async testInput(@Query() data: UserRoleCreateDto): Promise<any> {

    return data;
  }

and checking in bash:

curl 'http://localhost:3060/test_input?name=hello'

{"name":"HELLO"}

Check that you have ValidationPipe decorator and especially transform: true option, without these it doesn't work. transform: true automatically transforms input data to the class instance.

More about validation on the nestjs documentation page - link

Also, just in case, instead of @Query() decorator you can use @Body() for POST data or @Param() for URL parameters

3
votes

You can also use TypeORM's entity listeners.

@BeforeInsert

You can define a method with any name in entity and mark it with @BeforeInsert and TypeORM will call it before the entity is inserted using repository/manager save.

@Entity()
export class User {
    
    @BeforeInsert()
    nameToUpperCase() {
        this.email = this.email.toLowerCase()
        this.name = this.name.toUpperCase();
    }
}

Source here