0

I am facing this problem when I implemented a new module in my Nestjs API:

TypeError: this.subQuery is not a function

My project uses two databases each of them has its own entities and schemes as you see in the app.module.ts:

import { Module } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Product } from './product/product.entity';
import { User } from './user/user.entity';
import { Profile } from './profile/profile.entity';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './user/user.module';
import { ProductsModule } from './product/product.module';
import { ProfilesModule } from './profile/profile.module';
import { RolesGuard } from './auth/guards/roles.guard';
import { Path } from './path/path.entity';
import { Stage } from './stage/stage.entity';
import { TheoreticalQuestion } from './question/theoretical/theoretical_question.entity';
import { CodingQuestion } from './question/coding/coding_question.entity';
import { PathsModule } from './path/path.module';
import { StageModule } from './stage/stage.module';
import { QuestionModule } from './question/question.module';
import * as dotenv from 'dotenv';

dotenv.config();

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.UNIVERSAL_HOST,
      port: process.env.UNIVERSAL_PORT,
      username: process.env.UNIVERSAL_USERNAME,
      password: process.env.UNIVERSAL_PASSWORD,
      database: process.env.UNIVERSAL_NAME,
      entities: [Product, User, Profile],
      synchronize: true,
    }),
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.BANK_HOST,
      port: process.env.BANK_PORT,
      username: process.env.BANK_USERNAME,
      password: process.env.BANK_PASSWORD,
      database: process.env.BANK_NAME,
      entities: [Path, Stage, TheoreticalQuestion, CodingQuestion],
      synchronize: true,
    }),
    AuthModule,
    UsersModule,
    ProfilesModule,
    ProductsModule,
    PathsModule,
    StageModule,
    QuestionModule
  ],
  controllers: [AppController],
  providers: [AppService, { provide: APP_GUARD, useClass: RolesGuard }],
})
export class AppModule {}

The problem is comming from the path.service.ts which uses the second datasource and I am using query runner to interact with the dataSource:

import { Injectable } from '@nestjs/common';
import { Path } from './path.entity';
import { DataSource, InsertResult, QueryRunner } from 'typeorm';
import { executeUsingQueryRunner } from '../core/config/query_runner';

@Injectable()
export class PathsService {
  constructor(private dataSource: DataSource) {}

  async create(title: string, description: string, image: string): Promise<InsertResult> {
    return await executeUsingQueryRunner(this.dataSource, async (queryRunner: QueryRunner) => {
      return await queryRunner.manager.insert(Path, {title, description, image});
    });
  }
}

the executeUsingQueryRunner is just a function that create and connect the queryRunner.

export async function executeUsingQueryRunner(
  dataSource: DataSource,
  exec: (queryRunner: QueryRunner) => Promise<any>,
) {
  const queryRunner = dataSource.createQueryRunner();
  await queryRunner.connect();
  await queryRunner.startTransaction();
  try {
    return await exec(queryRunner);
  } catch (error) {
    await queryRunner.rollbackTransaction();
    throw error;
  } finally {
    //await queryRunner.commitTransaction();
    await queryRunner.release();
  }
}

the path.controller.ts :

import { Body, Controller, HttpCode, Post, UseGuards } from '@nestjs/common';
import { RolesGuard } from 'src/auth/guards/roles.guard';
import { UserRole } from 'src/core/constants/enums';
import { Roles } from 'src/user/roles.decorator';
import { Path } from './path.validator';
import { PathsService } from './path.service';

@Controller({
  path: 'paths',
  version: '1',
})
@UseGuards(RolesGuard)
@Roles(UserRole.SUPERADMIN, UserRole.BANKER)
export class PathsController {
  constructor(private pathsService: PathsService) {}

  @Post('create')
  @HttpCode(201)
  async create(@Body() {title, description, image}: Path) {
    return await this.pathsService.create(title, description, image);
  }
}

My entity is all good, I added the @Entity() notation and everything looks good, as well as my scheme.

Could anyone please give me a solution for that? Note that the services the uses the first dataSource are all working perfectly.

I found solutions that say that the datasource doesn't recognise the entity, but if make a change in the entity the app will auto migrate that change and it works all find but when it comes to the insertion the error shows up.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
MONSEF OT
  • 13
  • 3

0 Answers0