nestjs icon indicating copy to clipboard operation
nestjs copied to clipboard

Injecting dependency into `useFactory` results in error.

Open jdrskr opened this issue 3 years ago • 15 comments

Describe the bug From version 5.1.5 (PR) ImportingMikroOrm with forRootAsync and injecting any dependency in useFactory results in error.

Stack trace

TypeError: Cannot read properties of undefined (reading 'get')
    at Object.useFactory (/home/jdr/Workspace/xxx/src/api/core/core.module.ts:15:33)
    at Function.createEntityManager (/home/jdr/Workspace/xxx/node_modules/@mikro-orm/nestjs/mikro-orm-core.module.js:125:65)
    at Function.forRootAsync (/home/jdr/Workspace/xxx/node_modules/@mikro-orm/nestjs/mikro-orm-core.module.js:89:31)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

To Reproduce Steps to reproduce the behavior: Use MikroOrmModule.forRootAsync() and inject any dependency to useFactory.

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    MikroOrmModule.forRootAsync({
      inject: [ConfigService],
      useFactory: async (configService) => {
        return {
          entities: [
            './dist/domain/**/model/*.js',
          ],
          dbName: configService.get('database.name'),
          type: 'postgresql',
          user: configService.get('database.user'),
          password: configService.get('database.password'),
          port: configService.get('database.port'),
          host: configService.get('database.host'),
          migrations: {
            path: __dirname + './dist/persistence/migrations',
            pattern: /^[\w-]+\d+\.js$/,
          },
        };
      },
    })
  ]
})

Expected behavior You should be able to use async provider without any errors thrown.

Versions

Dependency Version
node 16.13.2
typescript 4.9.4
mikro-orm 5.6.2
mikro-orm/nestjs 5.1.5

jdrskr avatar Dec 27 '22 11:12 jdrskr

When I import ConfigModule (Without isGlobal) it works fine.

I have similar problem, I'm using forRootAsync with contextName: redshift, then I get an error when I want to use MikroORMModule.forFeature

Error: Nest can't resolve dependencies of the InactiveCustomerEntityRepository_redshift (?). Please make sure that the argument redshift_EntityManager at index [0] is available in the MikroOrmModule context.

BatuhanW avatar Dec 30 '22 16:12 BatuhanW

I kinda doubt this is something fixable from this package, its nest DI that is responsible for the injection.

B4nan avatar Dec 30 '22 17:12 B4nan

But it's working just fine with prior versions

jdrskr avatar Dec 30 '22 18:12 jdrskr

I've linked PR that breaks it

jdrskr avatar Dec 30 '22 18:12 jdrskr

Just look at what the PR does, how come it would be connected to nest DI not injecting a dependency? If it is, it still sounds like a nestjs bug to me.

B4nan avatar Dec 31 '22 08:12 B4nan

Could somebody provide a repository with this bug, not just the streets above but something I could just clone and start playing with, and I'll try to see if I can figure out what's up here?

jmcdo29 avatar Dec 31 '22 15:12 jmcdo29

This line seems suspicious to me. if someone sets up a useFactory in the async registration that has a value pissed to it, like the ConfigServive, but it's called directly without paying any necessary parameters, then an error like the one above would definitely be present

jmcdo29 avatar Dec 31 '22 15:12 jmcdo29

Can confirm that this issue arose for me after upgrading from 5.1.2 to 5.1.5. I've fallen back to 5.1.2 for now.

jblyberg avatar Jan 01 '23 21:01 jblyberg

This line seems suspicious to me. if someone sets up a useFactory in the async registration that has a value pissed to it, like the ConfigServive, but it's called directly without paying any necessary parameters, then an error like the one above would definitely be present

Right, I moved this into try/catch block to get around it but forgot it can be async as well.

Could you suggest a better way to let nest DI inject the dependencies? The idea behind those changes was to get resolve the same options as the ORM will get, and register the EM flavor based on the driver.

B4nan avatar Jan 03 '23 10:01 B4nan

I think you could probably create the entity manager as a provider so that the options can be injected into a factory for it. Would require a bit of re-work, but I think I might be able to help with that this week? I'll have to clone the repo and see what can be done there

jmcdo29 avatar Jan 03 '23 18:01 jmcdo29

That would be great!

B4nan avatar Jan 03 '23 18:01 B4nan

@B4nan question: if knex or mongo entity managers are available, should they override the original MikroORM entity manager?

Also, is there anywhere you would prefer to have brief conversation about the code other than this issue? I'm fine with here if that's your preference just want to make sure

jmcdo29 avatar Jan 03 '23 18:01 jmcdo29

Both should work, the one from core as well as the driver-specific implementation. They should resolve to the same - during runtime, it will be always the driver-specific implementation, but it's valid to inject it based on the import from core too. So in a way, those are just aliases. In the next major, if we find a good way to do what 5.1.5 tries to do, I'd like to drop the "old way" in favor of it, this shouldn't be driven by what package is installed.

Also, is there anywhere you would prefer to have brief conversation about the code other than this issue? I'm fine with here if that's your preference just want to make sure

It's fine here, or feel free to join the slack channel, I am there most of the time. I can do discord as well, but I don't keep that app open most of the time (unlike slack).

B4nan avatar Jan 03 '23 18:01 B4nan

If you pass contextname in the root (at the same level with useFactory), it works for me.

BatuhanW avatar Jan 08 '23 14:01 BatuhanW

I did a quick and dirty hotfix by awaiting the useFactory, which should fix the try/catch block. Keeping this open till we find a proper way.

Available in v5.1.6

B4nan avatar Jan 09 '23 20:01 B4nan

Closing as resolved via #166, will be part of v5.2.4

B4nan avatar Apr 17 '24 14:04 B4nan