【问题标题】:Import another module's repository in my module in nestjs在我的模块中在nestjs中导入另一个模块的存储库
【发布时间】:2020-03-04 15:02:45
【问题描述】:

我正在尝试使用 Nestjs 构建一个应用程序,目前我有两个模块:用户和身份验证,结构如下:

我需要将 UsersService 注入 AuthService 以便与 User 实体进行交互,所以我首先注入了 UsersRepository 进入 UsersService 并导出服务:

users.module.ts:

import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';

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

users.service.ts:

import { Injectable } from '@nestjs/common';
import { AuthCredentialsDto } from '../auth/dto/auth-credentials.dto';
import { JwtPayload } from '../auth/jwt-payload.interface';
import { User } from './user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UserRepository)
    private userRepository: UserRepository,
  ) {}

  async signUp(authCredentialsDto: AuthCredentialsDto): Promise<void> {
    return this.userRepository.signUp(authCredentialsDto);
  }

  async validateUserPassword(authCredentialsDto: AuthCredentialsDto): Promise<string> {
    return this.userRepository.validateUserPassword(authCredentialsDto);
  }

  async findOne({ username }: JwtPayload): Promise<User> {
    return this.userRepository.findOne({ username });
  }
}

users.repository.ts:

import { ConflictException, Injectable, InternalServerErrorException } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { Repository, EntityRepository } from 'typeorm';
import { User } from './user.entity';
import { AuthCredentialsDto } from '../auth/dto/auth-credentials.dto';

@Injectable()
@EntityRepository(User)
export class UserRepository extends Repository<User> {
  async signUp(authCredentialsDto: AuthCredentialsDto): Promise<void> {
    const { username, password } = authCredentialsDto;

    const salt = await bcrypt.genSalt();
    const user = new User();
    user.username = username;
    user.password = await this.hashPassword(password, salt);
    user.salt = salt;

    try {
      await user.save();
    } catch (error) {
      if (error.code === '23505') {
        throw new ConflictException('Username already exists');
      } else {
        throw new InternalServerErrorException();
      }
    }
  }

  async validateUserPassword(authCredentialsDto: AuthCredentialsDto): Promise<string> {
    const { username, password } = authCredentialsDto;
    const user = await this.manager.findOne(User, { username });

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

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

问题是当我需要从 AuthService 调用 UserService 方法时,我会收到以下格式的错误:

[Nest] 6267   - 11/08/2019, 3:30:52 AM   [ExceptionsHandler] Cannot read property 'findOne' of undefined +4600ms
TypeError: Cannot read property 'findOne' of undefined
    at UserRepository.validateUserPassword (/home/firiz/Projects/giftos/api/dist/users/user.repository.js:35:41)
    at UsersService.validateUserPassword (/home/firiz/Projects/giftos/api/dist/users/users.service.js:26:36)
    at AuthService.signIn (/home/firiz/Projects/giftos/api/dist/auth/auth.service.js:24:49)
    at AuthController.signIn (/home/firiz/Projects/giftos/api/dist/auth/auth.controller.js:26:33)
    at /home/firiz/Projects/giftos/api/node_modules/@nestjs/core/router/router-execution-context.js:37:29
    at process._tickCallback (internal/process/next_tick.js:68:7)

我的问题是......我错过了什么,导致这个痛苦的问题!

【问题讨论】:

  • 请贴出你的auth.module.ts文件的代码
  • 看到你正在扩展存储库,你不能打电话给this.findOne()吗?

标签: node.js typescript nestjs typeorm


【解决方案1】:

当您创建自定义存储库时,您应该直接使用它来扩展存储库,因此请尝试:

const user = await this.findOne(User, { username });

你可以找到more about custom repo and manager here

【讨论】:

  • 但这也不能解决问题。我也面临同样的问题。
【解决方案2】:

您不会导出和导入存储库,而是多次“重新创建”存储库。在要“重新创建” repo 的模块中(即 something.module.ts 文件),您应该使用所需的 repo 实体导入 TypeOrmModule。

例子:

@Module({
  imports: [
    TypeOrmModule.forFeature([
      ...
      MyEntity,
    ]),
    ...

...然后在模块的服务中:

export class MyService {
  constructor(
    @InjectRepository(MyEntity) private repo: Repository<MyEntity>,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多