How to globally inject value across modules in NestJS?
Asked Answered
V

1

15

I'm working with nx workspace and nestjs. I would like to inject a value across multiple modules in nestjs app.

Final goal is to reproduce similar way of configuration management as vsavkin mentioned for Angular

But it seems it's not possible, or I missed something.

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

How can I notify FeatureModule it needs to access to this global injected value ?

This is working fine inside AppService (service in root module), but not in any sub modules.

Here is my code below. Or an full example on codesandbox.io

app.module.ts

@Module({
  imports: [
    FeatureModule
  ],
  controllers: [
    AppController
  ],
  providers: [
    AppService,
    {
      provide: 'MY-TOKEN',
      useValue: 'my-injected-value',
    }
  ],
})
export class AppModule {}

feature.module.ts

@Module({
  imports: [],
  controllers: [],
  providers: [
    FeatureService
  ],
})
export class FeatureModule {
}

feature.service.ts

@Injectable()
export class AppService {
  constructor(
    @Inject('MY-TOKEN') private injectedValue: string
  ) {}
}
Violante answered 29/3, 2019 at 7:57 Comment(0)
H
28

Quote from NestJS official documentation:

In Angular, the providers are registered in the global scope. Once defined, they're available everywhere. On the other hand, Nest encapsulates providers inside the module scope. You aren't able to use the module providers elsewhere without importing them. But sometimes, you may just want to provide a set of things which should be available always - out-of-the-box, for example: helpers, database connection, whatever. That's why you're able to make the module a global one.

So what you can do is just defining one global module with that MY-TOKEN provider:


@Global()
@Module({  
  providers: [
    {
      provide: 'MY-TOKEN',
      useValue: 'my-injected-value',
    }
  ],
  exports: ['MY-TOKEN'],
})
export class GlobalModule {}

and then you can use its exported values without importing the global module anywhere.

Hendecahedron answered 29/3, 2019 at 8:48 Comment(3)
Works like a charm. Why I didn't think about it ! Thank you very much Karol. ;-)Violante
how about directly set the application module a global one, instead create a new module, is that ok?Inglebert
@KentWood doesn't work for some reason. It's needed to import global module into app.module, if you put global decorator on the app.module, nothing changesPresa

© 2022 - 2024 — McMap. All rights reserved.