The NestJs provider fails to inject and throws an error stating that this.iGalleryRepository.addImage is not a recognized function

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.

Answer №1

Finally, I managed to solve the issue.

dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter)

Although it was supposed to work, for some mysterious reason, it didn't. The .extend function wasn't behaving as expected, leading me to believe that either the extend method had a bug or my implementation was incorrect. So if you encounter this error, double-check your implementation first before trying something else.

To resolve it, all I did was

provide: DITokens.ImageDITokens.ImageRepository,
        useFactory: (dataSource: DataSource) => dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter),
        inject: [DITokens.CoreDITokens.DataSource]


changed it to

 provide: DITokens.ImageDITokens.ImageRepository,
        useClass: TypeOrmImageRepositoryAdapter

and surprisingly, it worked perfectly. It seems that referencing the repository in the class signature generates the TypeORM repository automatically.

I hope this solution works for you as well!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble encountered while configuring and executing Electron combined with React, Typescript, and Webpack application

I am currently in the process of migrating my Electron application from ES6 to Typescript. Despite successfully building the dll and main configurations, I encounter a SyntaxError (Unexpected token ...) when attempting to run the application. The project c ...

Angular 2 rc1 does not support ComponentInstruction and CanActivate

In the process of developing my Angular 2 application with Typescript using angular 2 rc.1, I've noticed that the official Angular 2 documentation has not been updated yet. I had references to ComponentInstruction Interface and CanActivate decorator ...

Warning: React has detected that a non-boolean value of `true` was received for the attribute `my-optional-property`

source code import React from "react"; import { Button, ButtonProps } from "@material-ui/core"; interface MyButtonProps extends ButtonProps { "aria-label": string; "my-optional-property"?: boolean; } function MyCustomButton(props: MyButtonProps) { ...

Utilizing the power of Typescript in Express 4.x

I'm currently working on building an express app using TypeScript and here is what my code looks like at the moment: //<reference path="./server/types/node.d.ts"/> //<reference path="./server/types/express.d.ts"/> import express = requir ...

What is the equivalent of Buffer.from(<string>, 'hex') in Python?

I am currently facing the challenge of translating a Typescript library into Python. The specific library I am working with is bs58 in Typescript and its counterpart base58 in Python. My issue arises when attempting to replicate the following code: const ...

The utilization of notifs (a variable of type []entity.Notif) as a string value in an array or slice literal is not permitted

I need to retrieve email data from the database in order to send an email using that information. This snippet of code found in controller/notif-controller.go: func (c *notifController) SendNotifEmail(context *gin.Context) { email_to := context.Query ...

Execute the PHP action on each individual element

I'm facing an issue with my PHP script that fetches data from a MySQL database. The problem is that the $result = $dao->joinedEvents($userId); function returns an array of numbers, but I need to run $secondResult = $dao->joinedEventsInfo($receiv ...

Stop openapi-generator from altering enum names in JavaScript/TypeScript

We have implemented the openapi generator to create our REST client and it has been quite effective. However, we encountered an issue when using enums in the format UPERCASE_UNDERSCORE, as it ended up removing the underscores which caused inconvenience. Th ...

After installing Angular 10, warnings about optimization for rxjs and lodash CommonJS or AMD dependencies may be displayed

After successfully upgrading my application from Angular 9 to Angular 10, I encountered some warnings when running the ng serve command. WARNING in src\app\auth\guard\auth.guard.ts depends on 'lodash'. CommonJS or AMD dependen ...

Encountering a 404 error for core.js and browser.js while loading an Angular 2 app through system.src.js

I am new to Angular2 and have followed the Angular2 quickstart and tutorial to get started. Just to provide some context, when a user clicks on a link in the top navigation bar of my webapp, it triggers a server side request. The resulting page returned t ...

Book of Tales displaying Emotion Styling upon initial load only

I'm currently working with the styled api provided by emotion in order to create a custom styled button. const StyledButton = styled(Button)` background-color: ${theme.palette.grey['800']}; width: 50; height: 50; &:hover { ba ...

Struggling to properly sort through my data in PHP and MySQL

I have a dataset that looks like this: a, b, c 1, 4, 7 2, 5, 8 3, 6, 9 My goal is to filter this data based on a selected column. For instance: In column 'a', search for the value 2. I attempted to create a variable for the chosen columns and ...

Event triggered by clicking on certain coordinates

Just starting with @asymmetrik/ngx-leaflet and Angular, so this might be a beginner's issue... I'm working on an Angular.io (v5) project that incorporates the @asymmetrik/ngx-leaflet-tutorial-ngcli Currently, I'm trying to retrieve the coo ...

What is the most efficient way to execute useEffect when only one specific dependency changes among multiple dependencies?

My main objective is to update a state array only when a specific state (loadingStatus) undergoes a change. Yet, if I include solely loadingStatus as a dependency, React throws an error requesting all dependencies [loadingStatus, message, messageArray, set ...

Transforming a function into an array in TypeScript

I attempted to use the map() function on a dataURL array obtained from the usePersonList() hook, but I am struggling to convert my function to an array in order to avoid errors when clicking a button. import Axios from "axios"; import React, { us ...

Having trouble grasping the concept of Interfaces and dealing with FormGroup problems in Angular?

Apologies if my question is a duplicate, I have found several solutions for the same issue on Stack Overflow, but unfortunately, I struggle to understand them in technical terms. Problem 1 src/app/models/dataModel.ts:2:5 2 id: number; ~~ The exp ...

Leveraging Typescript's robust type system to develop highly specific filter functions

I'm attempting to utilize the robust TypeScript type system in order to construct a highly typed 'filter' function that works on a collection (not just a simple array). Below is an illustration of what I am striving for: type ClassNames = &a ...

Retrieve the output of forkJoin subscription in Angular 6 using rxJs 6

A Straightforward Example: const tasks = []; for (let i = 0; i < this.initialData.length; i++) { tasks.push( this.taskService.getDetails(this.id1[i], this.id2[i]) }; combineLatest(...tasks).subscribe(taskGroup => { console.log(task ...

Tips for utilizing the Fluent UI Northstar Color Palette

When working with Fluent UI Northstar, one helpful feature is the color palette. While the documentation provides a list of color names and gradients that can be found here, it can be confusing on how to actually utilize these values (such as 100, 200, e ...

Create a PDF document utilizing Angular Ignite UI for Angular

Currently working with Angular TypeScript 12, I have successfully integrated Angular Ignite UI grid. However, I am in need of a way to export my grid into a PDF format using Igx-Grid. Does Igx-Grid support PDF exporting? If not, are there any alternative ...