3

I got the error message [Nest] 4492 - 06/17/2022, 17:59:11 ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'findOneByEmail') when creating a custom pipe for email validation registered.

i followed the answer: Email verification with class-validator in nestJS

is there something i missed?

// email-already-exist.pipe.ts

import { Injectable } from '@nestjs/common';
import {
  registerDecorator,
  ValidationOptions,
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from 'class-validator';

import { UsersService } from 'src/users/users.service';

@ValidatorConstraint({
  name: 'EmailAlreadyExist',
  async: true,
})
@Injectable()
export class EmailAlreadyExistConstraint
  implements ValidatorConstraintInterface
{
  constructor(private readonly usersService: UsersService) {}

  async validate(email: string) {
    return !(await this.usersService.findOneByEmail(email));
  }
}

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

// create-user.dto.ts

  @IsNotEmpty()
  @IsEmail()
  @EmailAlreadyExist({
    message: 'the email account already exist',
  })
  email: string;

// users.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { CreateUserDto } from 'src/users/dto/create-user.dto';
import { UpdateUserDto } from 'src/users/dto/update-user.dto';
import { UserEntity } from 'src/users/entities/user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UserEntity)
    private usersRepository: Repository<UserEntity>,
  ) {}

  async findOneByEmail(email: string) {
    return await this.usersRepository.findOneBy({ email: email });
  }
}

// users.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

import { UsersService } from 'src/users/users.service';
import { UsersController } from 'src/users/users.controller';
import { UserEntity } from 'src/users/entities/user.entity';
import { EmailAlreadyExistConstraint } from 'src/users/pipe/email-already-exist.pipe';

@Module({
  imports: [TypeOrmModule.forFeature([UserEntity])],
  controllers: [UsersController],
  providers: [UsersService, EmailAlreadyExistConstraint],
  exports: [UsersService],
})
export class UsersModule {}

and according to the answer from here TypeError: Cannot read properties of undefined on NestJS Dependency Injection I had to add @Injectable() but still not working

4
  • this is problably because that class EmailAlreadyExistConstraint isn't initialized by nestjs. Then marking when class-validator uses it. Commented Jun 17, 2022 at 12:08
  • no. it can work when i declare "return false" in validate method in email-already-exist.pipe.ts file. And the error message 'the email account already exists' is displayed Commented Jun 17, 2022 at 12:12
  • you didn't follow. EmailAlreadyExistConstraint will be initialized by class-validator, not by nestjs. Thus you cannot inject things in there Commented Jun 17, 2022 at 13:42
  • 1
    How did you resolve this? I'm stuck in the same problem and I don't know how to resolve it. Thanks Commented Oct 10, 2022 at 13:27

2 Answers 2

2

Try add this in you're app.ts

useContainer(app.select(AppModule), { fallbackOnErrors: true });

source

Sign up to request clarification or add additional context in comments.

Comments

0

Add the code below to the bootstrap function in your main.ts

useContainer(app.select(AppModule), { 
 fallbackOnErrors: true 
});

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.