Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nest can't resolve dependencies when importing a module with registerAsync

Im trying to import a Module with registerAsync and configure it with a provider I have in my module, but it throws an error it cant find this provider. What am I missing?

My Code:

import { CacheModule, Module } from '@nestjs/common';

@Module({
  imports:     [
    CacheModule.registerAsync({
      useFactory: async (options) => ({
        ttl: options.ttl,
      }),
      inject: ['MY_OPTIONS'],
    }),
  ],
  providers:   [
    {
      provide:  'MY_OPTIONS',
      useValue: {
        ttl: 60,
      },
    },
  ],
})
export class AppModule {
}

Error:

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

The example above is a simplification of my code. But the main issue stays the same: I do have a provider within the AppModule and I need it in the CacheModule.registerAsync() function.

If anyone wants to try figuring this out I made a really simple repository: https://github.com/MickL/nestjs-inject-existing-provider

like image 881
Mick Avatar asked Oct 26 '22 14:10

Mick


1 Answers

I'd say the problem is "CacheModule.registerAsync" and "AppModule" work at different levels, so defining a provider on "AppModule" does not make it available for "CacheModule.registerAsync".

Assuming we move the "MY_OPTIONS" to another module: "CacheConfigModule", it could look like:

CacheConfigModule.ts

import { Module } from '@nestjs/common';

@Module({
  providers: [
    {
      provide: 'MY_OPTIONS',
      useValue: {
        ttl: 60
      }
    }
  ],
  exports: ['MY_OPTIONS']
})
export class CacheConfigModule {}

AppModule.ts

import { CacheModule, Module } from '@nestjs/common';
import { CacheConfigModule } from './CacheConfigModule';

@Module({
  imports: [
    CacheConfigModule,
    CacheModule.registerAsync({
      imports: [CacheConfigModule],
      useFactory: async (options) => ({
        ttl: options.ttl
      }),
      inject: ['MY_OPTIONS']
    })
  ]
})
export class AppModule {}
like image 73
Alberto Martin Avatar answered Dec 02 '22 04:12

Alberto Martin