1
resposta

Erro no validador de nome único

Estou acompanhando o curso mas complementando o código do curso passado de Nest com essa aula de validação. Porém, estou recebendo o seguinte erro:

TypeError: (0 , is_name_unique_validator_1.IsNameUnique) is not a function
    at Object.<anonymous> (/home/emanuel.silva/Documentos/estudos/produtos-api/src/produto/produto.model.ts:22:16)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.<anonymous> (/home/emanuel.silva/Documentos/estudos/produtos-api/src/produto/produtos.service.ts:3:1)
    at Module._compile (node:internal/modules/cjs/loader:1103:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:

Segue minha classe de validador:

/* eslint-disable @typescript-eslint/ban-types */
import {
  ValidationArguments,
  ValidationOptions,
  ValidatorConstraint,
  ValidatorConstraintInterface,
  registerDecorator,
} from 'class-validator';

import { Injectable } from '@nestjs/common';
import { ProdutosService } from './produtos.service';

@Injectable()
@ValidatorConstraint()
export class IsNameUniqueConstraint implements ValidatorConstraintInterface {
  constructor(private produtoService: ProdutosService) {}

  validate(
    nomeProduto: string,
    validationArguments?: ValidationArguments,
  ): boolean | Promise<boolean> {
    return this.produtoService.obterPorNome(nomeProduto).then((produtos) => {
      if (produtos[0]) return false;
      return true;
    });
  }
}

export function IsNameUnique(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      constraints: [],
      validator: IsNameUniqueConstraint,
    });
  };
}

Aqui a forma como estou tentando chamar na entidade:

import { Column, DataType, Model, Table } from 'sequelize-typescript';
import { IsNotEmpty, IsString } from 'class-validator';

import { IsNameUnique } from './is-name-unique.validator';

@Table
export class Produto extends Model<Produto> {
  @Column({
    type: DataType.STRING(60),
    allowNull: false,
  })
  @IsNotEmpty()
  @IsString()
  codigo: string;

  @Column({
    type: DataType.STRING,
    allowNull: false,
  })
  @IsNotEmpty()
  @IsString()
  @IsNameUnique()
  nome: string;

  @Column({
    type: DataType.DECIMAL(10, 2),
    allowNull: false,
  })
  preco: number;
}
1 resposta

Oi Emanuel, tudo bem? Esse erro me parece muito estranho, basicamente ele tá dizendo que IsNameUnique não é uma função, mas claramente esse não é o problema. Tem dois pontos que eu verificaria.

  1. Seu IsNameUniqueConstraint tá decorado com @Injectable, ele foi listado no providers de algum módulo?
  2. O ValidatorConstraint precisa de um parâmetro { async: true } para configurar que esse validador é assíncrono.

Eu verificaria esses dois pontos e tentaria novamente. Caso não funcione, coloca seu projeto no GitHub e me manda a url, que eu posso clonar aqui e testar para encontrar o problema.