How I resolved circular dependecny in Nestjs guided by Errors

How I resolved circular dependecny in Nestjs guided by Errors

Before anything I want you to read this awesome article on circular dependency

https://wanago.io/2022/02/28/api-nestjs-circular-dependencies

There are 2 kinds of circular dependencies in Nest.js

  1. Module Circular dependencies

  2. Services Circular dependencies

Modules

Circular dependencies are difficult to reason about. Especially when there is a large number of modules involved. It's one thing to understand it with a trivial example like Module A -> Module B -> Module A But for nontrivial cases that are encountered in real life, it is very common for this chain to 10-15 modules long. Something like -

Module A -> Module B -> Module P -> Module X -> Module W -> Module Q -> Module R -> Module B -> Module S -> Module P

It is known that we have to use forwardRef to resolve circular dependencies but the question that arises is where do I apply forwardRef. I decided to use the information in Nest js errors after unsuccessfully trying to create some dependency graphs. Here is what the errors look like.

[ExceptionHandler] Nest cannot create the LocalFilesModule instance.
The module at index [2] of the LocalFilesModule “imports” array is undefined

So In this case I did what the error told me to do.

  1. Opened up LocalFilesModule file.

  2. In the imports array, at index 2 (indexes starts from 0), I added a forwardRef to the ModuleAt2Index .

  3. Then I was greeted with a similar error again only now the LocalFilesModule was changed with SomeOtherModule and the index was something else.

  4. So I went to step 1 again and repeated the same process until there were no more errors.

Services

The Circular dependency errors in services look like this.

Nest can't resolve dependencies of the FooService (?). Please make sure that the argument dependency at index [0] is available in the FooModule context.

Potential solutions:
- If dependency is a provider, is it part of the current FooModule?
- If dependency is exported from a separate @Module, is that module imported within FooModule?
  @Module({
    imports: [ /* the Module containing dependency */ ]
  })

Emboldened by my triumph in module circular dependency errors I decided to repeat my success with services circular dependency errors. So I again did what the error told me to.

  1. I opened FooModule.ts and checked if the MissingService 's module MissingServiceModule is present in FooModule 's imports array. It wasn't so I added it.

  2. This did resolve most of the errors but in case it didn't, I opened FooService and added a forwardRef on MissingService .

     constructor(
     @Inject(forwardRef(() => MissingService))
     readonly missingService: MissingService,  
     ){}
    

These errors indicated that code may be messed up and it's time to refactor. But I didn't have time for refactor right now so these errors were saved me. Hope it helps.