Solucionado (ver solução)
Solucionado
(ver solução)
14
respostas

Erro

Prezado, boa tarde

Estou seguindo o curso do NEST porem esse erro está aparecendo e mesmo verificando dado a dado ainda está dando o mesmo erro no user.entity.ts e user.service.ts; user.entity.ts:

  • @IsUserNameAlreadyTaken({
     message: 'userName is already taken' (e aqui)
    })* user.service.ts: @Injectable() export class UserService{ private users: Array = [{
     id: 1,
     *userName: 'admin',* (aqui está dando erro)
     email: 'admin@email.com',
     password: 'abc123',
     userFullName: 'admin',
     dateOfAdmission: new Date(),
    }];
14 respostas

Olá Lucas, tudo certinho?

Coloca o código completo da user.entity.ts para verificar como estão os atributos, em específico o userName. E coloca também um print com o erro apresentado pelo VSCode.

Porém antes de enviar, verifica se na classe da entidade user realmente existe o atributo userName, verificar também se o decorator está acima desse atributo. Se existir, verifica se está escrito corretamente, pois pode ocorrer de colocar uma letra maiúscula sem querer.

Olá segue o user.entity.ts, Insira aqui a descrição dessa imagem para ajudar na acessibilidade

E ai Lucas, tudo bem?

Ainda assim eu não consegui entender o erro. Faz o seguinte:

Coloca o mouse em cima da linha vermelha e mostra a mensagem que a IDE irá mostrar. Ou então o print do console que exibe o erro.

E mostra como está a implementação do seu validador.

Espero conseguir ajudar.

Haaa, eu vi agora...

No seu print não existe o atributo userName: string;, o qual os decorators serão utilizados.

@IsUserNameAlreadyTaken({
  message:'userName is already taken'
})
@IsNotEmpty({
  message:'the userName is required'
})
@IsString({
  message:'userName must beastring'
})
userName: string;   <<<< Está faltando este atributo.

Verifica se era isso.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Um dos erros é o que eu comentei no post anterior:

userName: string;   <<<< Está faltando este atributo na entity "user.entity.ts"

Esse você já colocou na classe?

Agora sobre o erro do { message: string; }, aparentemente a classe do decorator não está correspondente.

Poderias colocar também o arquivo todo onde está a classe do decorator?

Deverá ser algo desse tipo:

import { Injectable } from '@nestjs/common';
import {
  registerDecorator,
  ValidationArguments,
  ValidationOptions,
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from 'class-validator';
import { UsuarioService } from './usuario.service';

@Injectable()
@ValidatorConstraint()
export class IsUserNameAlreadyTakenConstraint implements ValidatorConstraintInterface {
  // injeção de dependência do seu service <<<<<<<<<<
  constructor(private usuarioService: UsuarioService) {}
  validate(
    userName: string,
    validationArguments?: ValidationArguments,
  ): boolean | Promise<boolean> {
    // chamada para o seu método no service <<<<<<<<<<<
    return !!!this.usuarioService.searchByUserName(userName);
  }
}

export function IsUserNameAlreadyTaken(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      // o método construtor do objeto em questão
      target: object.constructor, 
      // o nome da propriedade que está sendo validada
      propertyName: propertyName, 
      // as opções de validação, recebida como parâmetros do decorators
      options: validationOptions, 
      // validações extras. Validando quantidade mínima de 5 caracteres, no máximo 100, por exemplo
      constraints: [], 
      // a classe que implementa a interface "ValidatorConstraintInterface" que contém o método "validate", a real função que irá implementar a regra de validação
      validator: IsUserNameAlreadyTakenConstraint,
    });
  };
}

Lembrando que como a classe IsUserNameAlreadyTakenConstraint é Injectable() ela precisa ser colocada no array providers do seu user.module.ts, assim:

@Module({
  controllers: [UsuarioController],
  providers: [UsuarioService, IsUserNameAlreadyTakenConstraint], // <<< aqui
})
export class UsuarioModule {}

Verifica também o import de "ValidationOptions" na classe do decorator.

Qualquer coisa, detalhe melhor que a gente descobre.

Insira aqui a descrição dessa imagem para ajudar na acessibilidadeApós colocar userName: string e declarar o IsUserNameAlreadyTakenContraint no user.module.ts;

Poderias colocar também o arquivo todo onde está a classe do decorator "IsUserNameAlreadyTaken"?

O erro está na função que você implementou, provavelmente você está recebendo um parâmetro do tipo validatorOptions?: ValidatorOptions e deveria ser do tipo validationOptions?: ValidationOptions.

A sua classe deve está assim:

export function IsUserNameAlreadyTaken(validatorOptions?: ValidatorOptions) {
  ...
}

Deveria ser:

export function IsUserNameAlreadyTaken(validationOptions?: ValidationOptions) {
  ...
}

Veja que tem diferença de Validator para Validation

Altera o tipo do parâmetro que irá funcionar.

Abraço.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

solução!

Exatamente, o erro está na função "IsUserNameAlreadyTaken" que você implementou, está recebendo um parâmetro do tipo validatorOptions?: ValidatorOptions e deveria ser do tipo validationOptions?: ValidationOptions.

Um pequeno detalhe.

Se conseguiu, marca o post como resolvido para ajudar o pessoal que poderá passar por isso.

Deu certo, muito obrigado

Desculpa a dor de cabeça, = )

Estamos aqui para se ajudar.

Marca ai como resolvido.

Valeu.

Fala Lucas, blz?

Não esquece de marcar o tópico como resolvido, pra ajudar outras pessoas.

Abraço

Fala Lucas, blz?

Não esquece de marcar o tópico como resolvido, pra ajudar outras pessoas.

Abraço

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software