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.