1

How can I inject a service into an nestjs-i18n I18nResolver?

The docs state that:

To implement your own resolver (or custom logic) use the I18nResolver interface. The resolvers are provided via the nestjs dependency injection, this way you can inject your own services if needed.

My Resolver looks the following:

// AppLanguageResolver.ts


import {ExecutionContext, Inject, Injectable, Scope} from "@nestjs/common";
import {I18nResolver} from "nestjs-i18n";
import {UserService} from "@root/services/user-service/user.service";

@Injectable()
export class AppUserLanguageResolver implements I18nResolver {
    constructor(private userService: UserService) {}

    resolve(context: ExecutionContext): Promise<string | string[] | undefined> | string | string[] | undefined {
        console.log("AppUserLanguageResolver");
        return undefined;
    }

}

And in my app.module.ts ive added the module configuration:

// app.module.ts

@Module({

  providers: [
    UserService,
    AppUserLanguageResolver,
  ],
  imports: [
    I18nModule.forRoot({
      fallbackLanguage: 'en',
      parser: I18nJsonParser,
      parserOptions: {
        watch: APP_ENV === AppEnv.Dev,
        path: path.join(__dirname, '/i18n/translations'),
      },
      resolvers: [
        AppUserLanguageResolver
      ]
    }),
  ]

});

But running the app tells me that nesjs cannot resolve the dependencies:

[Nest] 5876   - 20/02/2022, 19:21:58   [ExceptionHandler] Nest can't resolve dependencies of the AppUserLanguageResolver (?). Please make sure that the argument UserService at index [0] is available in the I18nModule context.
                                                                                                                                                                                                                                 
Potential solutions:                                                                                                                                                                                                             
- If UserService is a provider, is it part of the current I18nModule?                                                                                                                                                            
- If UserService is exported from a separate @Module, is that module imported within I18nModule?                                                                                                                                 
  @Module({                                                                                                                                                                                                                      
    imports: [ /* the Module containing UserService */ ]                                                                                                                                                                         
  })
 +17ms
Error: Nest can't resolve dependencies of the AppUserLanguageResolver (?). Please make sure that the argument UserService at index [0] is available in the I18nModule context.

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

    at Injector.lookupComponentInParentModules (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:192:19)
    at async Injector.resolveComponentInstance (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:148:33)
    at async resolveParam (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:102:38)
    at async Promise.all (index 0)
    at async Injector.resolveConstructorParams (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:117:27)
    at async Injector.loadInstance (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:81:9)
    at async Injector.loadProvider (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\injector.js:38:9)
    at async Promise.all (index 15)
    at async InstanceLoader.createInstancesOfProviders (D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\instance-loader.js:43:9)
    at async D:\dev\projects\project\workspace\packages\app-backend\node_modules\@nestjs\core\injector\instance-loader.js:28:13

UserService is injected in Scope.Request but removing or changing the scopes did not have any effect. I also havent found any information regarding this issue.

How can I fix this?

Code Spirit
  • 3,992
  • 4
  • 23
  • 34
  • Have you found any solution to solve this? because I have the same problem and if you managed to find any solution please share it here, thanks. – Aspian Jun 25 '22 at 09:09

3 Answers3

0

Maybe you forgot to export UserService.

0

The services that pass as arguments to nestjs-i18n custom resolver's constructor must be Global to be accessible. So, in your case, you should make your user module global, and then everything will be working as expected.

For example in your user module file you should do something like this:

//user.module.ts

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

@Global() // <----- Add this
@Module( {
  imports: [ TypeOrmModule.forFeature( [ User ] ) ],
  controllers: [ UserController ],
  providers: [ UserService ]
} )
export class UserModule { }
Aspian
  • 1,865
  • 3
  • 24
  • 31
0

You should define async config instead of sync config and import module that contains your service. To do it you should refactor your code in the following way:

@Module({
  imports: [
    I18nModule.forRootAsync({
      useFactory: () => ({
        fallbackLanguage: 'en',
        parser: I18nJsonParser,
        parserOptions: {
          watch: APP_ENV === AppEnv.Dev,
          path: path.join(__dirname, '/i18n/translations'),
        },
      }),
      resolvers: [AppUserLanguageResolver],
      imports: [UserModule]
    }),
  ]
});
Jakub
  • 3
  • 1