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.