Search code examples
postgresqlnestjstypeormclass-validatorclass-transformer

How can I set a default value to a property if it is not defined after class validator in nestjs?


my project's product controller allows users to register a product with partial data of product entity, and then if admin approves the product, the users can add more data to the product entity with update entrypoint. But the problem is that my createProductDto class misses part of the entity columns, and productRepo.save(productRepo.create(dto)) using typeorm, causes error, saying PostgreSQL Not-Null Constraint. For example,

product.entity.ts

@Entity()
class Product {
  @Column()
  registerData: string;

  @Column()
  saleData: string;
}

create-product.dto.ts

class CreateProductDto {
  @IsString()
  @Type(() => String)
  registerData;
}

product.service.ts

class ProductsService {
  constructor(@InjectRepository(Product) private productRepo: Repository<Product>) {}

  async register(createProductDto: CreateProductDto) {
    const product = productRepo.create(createProductDto);
    return productRepo.save(product);
  }
}

so, I want to set default values in the dto. I tried to set defalut values in the class, but class validator's option, forbidNonWhitelisted, does not allows to have default values. Is there a way to set default values after validation?

In my project, product entity has three connected tables, and the total number of properties is about 30. and user can register only with 10 properties while the rest of them should be default value. I know @Column({defalut: value}) can work. but different user have different registration process with different default values.


Solution

  • First, set the option transform: true in your ValidationPipe, this will make the deserialized class instance the value that @Body() gets instead of just the validated JSON.

    Next, add the optional property to your DTO and validate it with @IsOptional() along with whatever other validations it should have. Lastly, give it the default value via property = defaultValue. This way, when class-transformer creates the class instance, if there is no value for property it'll have the default value and class-validator will validate it accordingly and let it pass.