简体   繁体   中英

Using class-validator in service nestjs?

class-validate always return length = 0 when I try use it in service.

service

export class UserService extends BaseService<UserEntity> {
  private validator
  constructor (
    @Inject('USER_RESPOSITORY')
    private userRespository: typeof UserEntity
  ) {
    super(userRespository)
    this.validator = new Validator()
  }

  async create (user: CreateUserDto): Promise<UserEntity> {

    const error = await this.validator.validate(user)

    if (error.length > 0) {
      throw Error('Invalid criterial!')
    }

    const hashedPassword = await bcrypt.hash(user.password, 10);
    user.password = hashedPassword
    
    const rs = await super.create(user)

    return rs
  }

}

controller:

@Post()
async create (@Body() user) {
    return this.userService.create(user)
}

dto:

export class CreateUserDto {
  @IsEmail()
  email: string

  @Length(8)
  password: string

  @IsOptional()
  isSuperAdmin: number
}

value input: { "email": "nhathanluu", "password": "nhathan12" }

class-validate.validate() return empty array. It fine when I validate in controller

You are taking a plain JavaScript object and validating it. It's not an instance of CreateUserDto . The validator does not know about the decorators which provide the validation metadata. It is just validating a plain JS object. The validator will not find any metadata informing it how to validate it. It will consider it valid.

async isValid(user: CreateUserDto): Promise<boolean> {
  const validator = new Validator();
  const errors = await validator.validate(user);

  return errors.length === 0;
}

const isValid = await this.isValid({ email: 'john', password: 'test' });
// ==> returns true

In case of your controller it is NestJS which transforms it to an instance of CreateUserDto and then performs the validation.

Make sure you are dealing with an instance of CreateUserDto . You can use the class-transformer package to do so or you can set the transform option on NestJS's validation pipe. That way it will convert it to such an instance for you.

@Body(new ValidationPipe({ transform: true })) user: CreateUserDto

In case you are using a global ValidationPipe you can also set the transform option there, but of course that impacts all endpoints.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM