#circular dependends on each other

22 messages · Page 1 of 1 (latest)

raw cloud
#

so yeah i ran into a circular dependency issue

i got 2 services
one is my AccountService and the other is a common service i use on several places called TokenService
they both need to use each other, what can be done about this

uncut monolith
#

Why does TokenService need AccountService? Or the other way around? Is there a method that could be moved to a new service, say AuthService, which would eliminate the need?

raw cloud
# uncut monolith Why does TokenService need AccountService? Or the other way around? Is there a m...

actually this didn't used to be the case
and unfortunate not

i'm working on 2fa atm and needed to re-use the auth system to re-auth a user
so 2fa cant be disabled so easy and since it is related to tokens i moved it out of the accountService into the tokenservice

usually you would just ask for the user's password
but i'm not using any passwords shrugakko
instead i use magic links for auth

PS: appreciate the fast response here since i gant go further without solving this

raw cloud
#

the reason why this happens
is because in order to request a loginToken

the account needs to be fetched

so tokenService needs: AccountService
but AccountService needs: TokenService to make the login work

uncut monolith
#

Difficult to say without the code, but here's a suggestion:

// say you have something like this
class TokenService {
    do2FA(accountId: string) {
        const account = this.accountService.getAccount(accountId);
        const token = whetever(account);
    }
}

// to remove the dependency, you can do this

class TokenService {
    do2FA(account: Account) { 
        // now it's not dependent on AccountService
        const token = whetever(account);
    }
}

class NewService {
    constructor(private tokenService: TokenService, private accountService: AccountService) {}
    
    do2FA(accountId: string) { // use this method instead
        const account = this.accountService.getAccount(accountId);
        return this.tokenService.do2FA(account);
    }
}
raw cloud
uncut monolith
#

Then you would put NewService into a new module, import both, and remove accessmodule from tokenmodule.

Or you can use forwardref: https://docs.nestjs.com/fundamentals/circular-dependency but I usually end up with better code when I actually split the services/modules to avoid the circular dependency.

raw cloud
raw cloud
#

btw this circular is happening at the controller level rather then the serice

#

should have said that sooner

uncut monolith
#

controller depending on controller?

raw cloud
#

no i would't say that, this thing is messy atm need to figure out what is going wrong exactly

#

here is the full error

[Nest] 37463  - 10/12/2023, 2:52:41 PM   ERROR [ExceptionHandler] Nest cannot create the TokenModule instance.
The module at index [1] of the TokenModule "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [1] is of type "undefined". Check your import statements and the type of the module.

Scope [AppModule -> AccountModule]
Error: Nest cannot create the TokenModule instance.
The module at index [1] of the TokenModule "imports" array is undefined.

Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [1] is of type "undefined". Check your import statements and the type of the module.

Scope [AppModule -> AccountModule]
    at DependenciesScanner.scanForModules (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/scanner.js:60:23)
    at DependenciesScanner.scanForModules (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/scanner.js:68:32)
    at DependenciesScanner.scanForModules (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/scanner.js:68:32)
    at DependenciesScanner.scan (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/scanner.js:27:9)
    at /home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/nest-factory.js:107:17
    at Function.asyncRun (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/errors/exceptions-zone.js:22:13)
    at NestFactoryStatic.initialize (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/nest-factory.js:106:13)
    at NestFactoryStatic.create (/home/weshuiz13/Documents/nest-server/node_modules/@nestjs/core/nest-factory.js:42:9)
    at bootstrap (/home/weshuiz13/Documents/nest-server/src/main.ts:21:15)
#

accountService uses TokenService in both service and controller
while tokenService doesn't have a controller and just uses AccountService in the service

uncut monolith
uncut monolith
raw cloud
raw cloud
uncut monolith
#

Sounds like these 2 methods could fit into something new like MagicLinkService.

raw cloud
#

prob best to put it in the common folder

prisma raptor
#

circular dependends on each other