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

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

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.

import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { Injectable } from '@nestjs/common';
import { UserService } from './user.service';

@ValidatorConstraint({ name: 'unique', async: true })
@Injectable()
export class UniqueFieldValidator implements ValidatorConstraintInterface {
  constructor(private readonly userService: UserService) {
  }

  validate = async (value: any, args: ValidationArguments): Promise<boolean> => {
    console.log(this.userService); // <-- This log prints undefined
    const [entityClass, fieldName] = args.constraints;
    const entity = await this.userService.findByFieldValue({ [fieldName]: value });
    return !entity;
  }

  defaultMessage(args: ValidationArguments) {
    const [entityClass, fieldName] = args.constraints;
    return `${fieldName} must be unique`;
  }
}

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

import { IsEnum, IsNotEmpty, MinLength, Validate } from "class-validator";
import { CompanyStatuses } from "src/company/dto/company.enums";
import { User } from "../entities/user.entity";
import { UniqueFieldValidator } from "../unique-field-validator";

export class CreateUserDto {

    @IsNotEmpty()
    @MinLength(3)
    @Validate(UniqueFieldValidator, [User, 'username'])
    username: string
}

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

    TypeError: Cannot read properties of undefined (reading 'findByFieldValue')
    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.

import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { UniqueFieldValidator } from './unique-field-validator';

@Module({
  controllers: [UserController],
  providers: [UserService,UniqueFieldValidator],
  imports: [TypeOrmModule.forFeature([User])],
  exports: [UserService,TypeOrmModule]
})
export class UserModule { }

答案1

得分: 2

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

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

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

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { useContainer } from 'class-validator';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  useContainer(app.select(AppModule), { fallbackOnErrors: true });
  await app.listen(3000);
}

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.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { useContainer } from 'class-validator';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  useContainer(app.select(AppModule), { fallbackOnErrors: true });
  await app.listen(3000);
}
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:

确定