nestjs / typeorm

TypeORM module for Nest framework (node.js) 🍇

Home Page:https://nestjs.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TypeError: Cannot read property 'findOne' of undefined

arslanmughal99 opened this issue · comments

I'm submitting a...


[ ] Regression 
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

TypeError: Cannot read property 'findOne' of undefined

Expected behavior

UserRepository.findOne() shouldn't be undefined

Minimal reproduction of the problem with instructions

user.repository.ts


@EntityRepository(UserEntity)
export class UserRepository extends Repository < UserEntity > {
    async signUp(userRegistration: UserRegisterationDto): Promise {
        const { firstName, lastName, username, email, countryState, country, countryCode, dob, password, phone } = userRegistration;
        const newUser = new UserEntity();
        newUser.firstName = firstName;
        newUser.lastName = lastName;
        newUser.email = email;
        newUser.countryState = countryState;
        newUser.country = country;
        newUser.countryCode = countryCode;
        newUser.dob = new Date(dob);
        newUser.phone = phone
        newUser.username = username;
        newUser.salt = await bcrypt.genSalt()
        newUser.password = await this.hashPassword(password, newUser.salt);
        newUser.verified = false;
        try {
            await newUser.save();
        } catch (err) {
            if (err.code === '23505') throw new ConflictException('User Conflict')
            throw new InternalServerErrorException('Internal Server Error');
        }
    }

    async validateCredential(userSignIn: SignInDto): Promise {
        const query = this.connection.createQueryBuilder(UserEntity, 'user');
        const { password, username } = userSignIn;

        const user: UserEntity = await query.where('user.username = :username', { username }).orWhere('user.email = :username', { username }).getOne();

        if (user && await user.validatePassword(password)) {
            return user.username;
        } else {
            return null;
        }
    }

    async hashPassword(password: string, salt: string): Promise {
        return await bcrypt.hash(password, salt);
    }

} 

role.guard.ts


@Injectable()
export class RoleGuard implements CanActivate {
    constructor(
        @InjectRepository(UserRepository)
        private readonly userRepository: UserRepository,
        private readonly reflector: Reflector,
        private readonly jwtService: JwtService
    ) { }

    getRequest(context: ExecutionContext) {
        const ctx = GqlExecutionContext.create(context);
        return ctx.getContext().req;
    }

    async canActivate(context: ExecutionContext): Promise {
        const req = this.getRequest(context);
        const roles = this.reflector.getAll('roles', [context.getHandler()])
        const authHeader = req.headers.authorization as string;

        if (!authHeader) return false;
        const [type, token] = authHeader.split(' ');

        if (type !== 'Bearer') return false;
        try {
            const { username, role }: JwtPayload = await this.jwtService.verifyAsync(token);
 // Issue is causing in below line
            const user: UserEntity = await this.userRepository.findOne({ username });
            console.log(user); // Just temporary logging to test 
            return true;
        } catch(err){
            console.log("USER ERROR: ", err);
            return false;
        }
    }
}

What is the motivation / use case for changing the behavior?

I have used same way in my other project and it is working okay
but with perticular project it is not throwing TypeError: Cannot read property 'findOne' of undefined

Environment


Nest version: X.Y.Z
   "@nestjs/common": "^7.0.0",
    "@nestjs/core": "^7.0.0",
    "@nestjs/graphql": "^7.1.5",
    "@nestjs/jwt": "^7.0.0",
    "@nestjs/platform-express": "^7.0.0",
    "@nestjs/typeorm": "^7.0.0",
 
For Tooling issues:
- Node version: v12.6.0  
- Platform: Windows 

Others:
Is there something wrong in my code ?

Please, use our Discord channel (support) for such questions. We are using GitHub to track bugs, feature requests, and potential improvements.

So my solution was to replace this

export class UserService {
    constructor(
         @InjectRepository(UserRepository)
         private userRepository: UserRepository;

         @InjectRepository(AuthRepository)
         private authRepository: AuthRepository;
     ) {  }
}

with this using Connection from typeorm

export class UserService {
    private userRepository: UserRepository;
    private authRepository: AuthRepository;
    constructor(
        private readonly connection: Connection
    ) {
        this.userRepository = this.connection.getCustomRepository(UserRepository);
        this.authRepository = this.connection.getCustomRepository(AuthRepository);
    }
}

Now it work like charm :)

I have the same problem, version info:

 "@apollo/federation": "0.20.0",
"@nestjs/common": "^7.0.0",
"@nestjs/core": "^7.0.0",
"@nestjs/graphql": "^7.7.0",
"@nestjs/platform-express": "^7.0.0",
"@nestjs/swagger": "^4.6.1",
"@nestjs/typeorm": "^7.1.4",
"apollo-server-express": "^2.18.2",
"graphql": "^15.3.0",
"graphql-tools": "^6.2.4",
"graphql-type-json": "0.3.1",
"mysql": "^2.18.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^6.5.4",
"swagger-ui-express": "^4.1.4",
"typeorm": "^0.2.28"

LOG INFO:
TypeError: Cannot read property 'findOne' of undefined",
" at ThreatRepository.Repository.findOne (/Users/XXX/workstation/XXX/node_modules/typeorm/repository/Repository.js:174:29)",

I am having the same issue.

An alternative? I am not convinced about injecting the connection at service layer to get the repositories.
Why the undefined error happens in first place?

I inject the repository and it is defined but when I call findOne it says it's undefined.

If you're still having a problem with this, please provide a minimum reproduction repository. This is almost always a configuration problem

I will try create a repository to reproduce the error.

For the moment I can give you this link where I posted most of my configuration. The question is different because there I was trying to use conncetion.getCustomRepository but it doesn't work either.

Please create a separate issue & provide a minimum reproduction repository.