I'm currently working on developing a NestJS TypeScript backend application that interacts with MySQL as its database, following the principles of clean architecture. My implementation includes JWT and Authorization features. However, I seem to be encountering issues with my function due to problems related to dependency injection. To resolve this, I'll share relevant files here, but please let me know if you require access to any additional files for debugging purposes. I've been troubleshooting this problem for the past 3-4 days. :/
Full Error :
ERROR Method: POST; Path: /images/add; Error: this.iGalleryRepository.addImage is not a function
The module "AppModule" is named as .RootModule where I package my app:
@Module({
imports: [
InfraModule,
AuthModule,
UserModule,
ImageModule
]
})
export class RootModule { }
Here's the structure of the Image Module:
const persistenceProviders: Provider[] = [
{
provide: DITokens.ImageDITokens.ImageRepository,
useFactory: (dataSource: DataSource) => dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter),
inject: [DITokens.CoreDITokens.DataSource]
}
];
@Module({
controllers: [
ImageController
],
providers: [
...persistenceProviders,
ImageService,
ImageHandler
]
})
export class ImageModule { }
You might wonder about the definition of the database:
export const databaseProviders = [
{
provide: DITokens.CoreDITokens.DataSource,
useFactory: async () => {
return AppDataSource.initialize();
}
}
];
.
.
.
@Global()
@Module({
imports: [
CqrsModule,
],
providers: [
...providers,
...databaseProviders
],
exports: [
DITokens.CoreDITokens.CommandBus,
DITokens.CoreDITokens.QueryBus,
DITokens.CoreDITokens.EventBus,
...databaseProviders
]
})
export class InfraModule implements OnApplicationBootstrap {
onApplicationBootstrap(): void {
initializeTransactionalContext();
}
}
Details about the Image Controller:
It's worth noting that the line Logger.log(adapter, "CreateImageDTO") works fine and outputs correctly, but the subsequent line Logger.log(createdImage, "createdImage") seems to have an issue.
@Controller('images')
@ApiTags('images')
export class ImageController {
constructor(
private readonly imageService: ImageService,
private readonly imageHandler: ImageHandler,
) { }
@Post("add")
@HttpCode(HttpStatus.OK)
@ApiBody({ type: HttpRestApiModelCreateImageBody })
@ApiResponse({ status: HttpStatus.OK, type: HttpRestApiResponseImage })
public async createImage(
@Body() body: HttpRestApiModelCreateImageBody
): Promise<CoreApiResponse<ImageUseCaseDTO>> {
const adapter: ICreateImageDTO = await CreateImageDTO.new({
parentId: body.parentId,
title: body.title,
imageUrl: body.imageUrl,
type: body.type
});
Logger.log(adapter, "CreateImageDTO")
const createdImage: ImageUseCaseDTO = await this.imageService.createImage(adapter);
Logger.log(createdImage, "createdImage")
return CoreApiResponse.success(createdImage);
}
}
Information regarding the Image Service:
@Injectable()
export class ImageService {
/**
* @param {IGalleryRepository} iGalleryRepository
*/
constructor(
@Inject(DITokens.ImageDITokens.ImageRepository)
private readonly iGalleryRepository: IGalleryRepository
) { }
public async createImage(payload: ICreateImageDTO): Promise<ImageUseCaseDTO> {
const image: Image = await Image.new({
title: payload.title,
type: payload.type,
parentId: payload.parentId,
imageUrl: payload.imageUrl
})
await this.iGalleryRepository.addImage(image);
return ImageUseCaseDTO.newFromImage(image);
}
}
Error description from the above code snippet mentioned earlier
When attempting to log this.iGalleryRepository using console.log(), the output is as follows:
Repository {
target: [class TypeOrmImage],
manager: <ref *1> EntityManager {
'@instanceof': Symbol(EntityManager),
repositories: [ [Repository], [Repository] ],
treeRepositories: [],
plainObjectToEntityTransformer: PlainObjectToNewEntityTransformer {},
connection: DataSource {
'@instanceof': Symbol(DataSource),
migrations: [],
subscribers: [],
entityMetadatas: [Array],
name: 'default',
options: [Object],
logger: [AdvancedConsoleLogger],
driver: [MysqlDriver],
manager: [Circular *1],
namingStrategy: [DefaultNamingStrategy],
metadataTableName: 'typeorm_metadata',
queryResultCache: undefined,
relationLoader: [RelationLoader],
relationIdLoader: [RelationIdLoader],
isInitialized: true
}
},
queryRunner: undefined
}
Your assistance is greatly appreciated in advance.