如何在Nest JS中使用class-validator添加唯一字段验证。

huangapple go评论109阅读模式
英文:

How to add unique field validation in nest js with class-validator

问题

我了解你的问题,你在NestJS中使用class-validator进行数据库字段验证时遇到了一些问题。在你的代码中,UniqueFieldValidator类的构造函数依赖于userService,但在validate函数中,userService却变成了undefined。这可能是由于依赖注入的问题造成的。以下是一种可能的解决方案:

首先,确保在UniqueFieldValidator类中的构造函数上使用了@Injectable()装饰器,以便NestJS可以正确注入userService。你的代码中已经包含了这个装饰器,这是正确的。

接下来,检查一下你的NestJS模块(UserModule)的提供者数组中是否正确引入了UserServiceUniqueFieldValidator。你的代码中也已经包含了它们,这也是正确的。

然后,确保你的UserModule正确导入了TypeOrmModule,并且已经正确配置了实体(User)。你的代码中也已经包含了这些部分。

最后,确保你的UniqueFieldValidator被正确引用并传递给@Validate装饰器。

总结一下,根据你提供的代码片段,似乎配置和装饰器都已经正确设置。如果仍然遇到问题,可以检查以下几点:

  1. 确保NestJS应用程序正确启动,并且UserModule已被正确引入。
  2. 检查是否有任何循环依赖问题,可能会导致userService未能正确注入。

如果仍然存在问题,可以提供更多关于应用程序的信息,以便更深入地了解问题所在。

英文:

How to do validation with database like unique filed validation in nest JS using the class validator?

I created a custom validation class and tried it. But userService was undefined when I console log that service in the validate function.

  1. import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
  2. import { Injectable } from '@nestjs/common';
  3. import { UserService } from './user.service';
  4. @ValidatorConstraint({ name: 'unique', async: true })
  5. @Injectable()
  6. export class UniqueFieldValidator implements ValidatorConstraintInterface {
  7. constructor(private readonly userService: UserService) {
  8. }
  9. validate = async (value: any, args: ValidationArguments): Promise<boolean> => {
  10. console.log(this.userService); // <-- This log prints undefined
  11. const [entityClass, fieldName] = args.constraints;
  12. const entity = await this.userService.findByFieldValue({ [fieldName]: value });
  13. return !entity;
  14. }
  15. defaultMessage(args: ValidationArguments) {
  16. const [entityClass, fieldName] = args.constraints;
  17. return `${fieldName} must be unique`;
  18. }
  19. }

I have called this class in side createUserDto Class as below.

  1. import { IsEnum, IsNotEmpty, MinLength, Validate } from "class-validator";
  2. import { CompanyStatuses } from "src/company/dto/company.enums";
  3. import { User } from "../entities/user.entity";
  4. import { UniqueFieldValidator } from "../unique-field-validator";
  5. export class CreateUserDto {
  6. @IsNotEmpty()
  7. @MinLength(3)
  8. @Validate(UniqueFieldValidator, [User, 'username'])
  9. username: string
  10. }

UniqueFieldValidator class is calling successfully.
But because that userServices is undefined in the validate function when I sent the request to create a user, it's returning the error message saying

  1. TypeError: Cannot read properties of undefined (reading 'findByFieldValue')
  2. at UniqueFieldValidator.validate

If anyone has experience this in NestJs with class-validator please help me. Thank you!

P.S.

Below code shows how i have written my userModule and i have added both UserService and Validator class to the Providers array.also have placed @injectable() decorator top of the UserService class. but it's not working still.

  1. import { Module } from '@nestjs/common';
  2. import { UserService } from './user.service';
  3. import { UserController } from './user.controller';
  4. import { TypeOrmModule } from '@nestjs/typeorm';
  5. import { User } from './entities/user.entity';
  6. import { UniqueFieldValidator } from './unique-field-validator';
  7. @Module({
  8. controllers: [UserController],
  9. providers: [UserService,UniqueFieldValidator],
  10. imports: [TypeOrmModule.forFeature([User])],
  11. exports: [UserService,TypeOrmModule]
  12. })
  13. export class UserModule { }

答案1

得分: 2

Sure, here's the translation of the provided text:

是的!我找到了解决方案,并将其发布在我的问题中,以帮助将来遇到此问题的人。
只需在根方法中添加 useContainer(app.select(AppModule), { fallbackOnErrors: true });

然后我的 main.ts 文件如下所示。

  1. import { NestFactory } from '@nestjs/core';
  2. import { AppModule } from './app.module';
  3. import { useContainer } from 'class-validator';
  4. async function bootstrap() {
  5. const app = await NestFactory.create(AppModule);
  6. useContainer(app.select(AppModule), { fallbackOnErrors: true });
  7. await app.listen(3000);
  8. }
  9. bootstrap();

我将这个帖子发布在我的问题中,以帮助将来的某人。

英文:

Yeah! I found a solution and posting it to my own question for help to someone getting this issue in the future.
Just add useContainer(app.select(AppModule), { fallbackOnErrors: true }); in your root method.

Then my main.ts was like this.

  1. import { NestFactory } from '@nestjs/core';
  2. import { AppModule } from './app.module';
  3. import { useContainer } from 'class-validator';
  4. async function bootstrap() {
  5. const app = await NestFactory.create(AppModule);
  6. useContainer(app.select(AppModule), { fallbackOnErrors: true });
  7. await app.listen(3000);
  8. }
  9. bootstrap();

I'm posting this to my own question to help someone in the future.

huangapple
  • 本文由 发表于 2023年3月7日 17:51:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定