How to use @RequestModule()
aryagelato opened this issue · comments
Is there an existing issue for this?
- I have searched the existing issues
Current behavior
I was trying to import a service into the command by Dependency Injection but it gives me an error:
ERROR [CommandRunnerService] A service tried to call a property of "undefined" in the EcomProductEventsHandleCommand class. Did you use a request scoped provider without the @RequestModule() decorator?
I have checked your documentation and there is no example of it!
Minimum reproduction code
import { Command, CommandRunner, Option } from 'nest-commander';
import { Logger } from '../../common/logger/logger.service';
import { PriceRmqHandlerService } from '../services/price-rmq-handler.service';
interface CommandOptions {
data?: string;
}
@Command({ name: 'ecom-product-events-handle', description: 'Handling product events from shared bus' })
export class EcomProductEventsHandleCommand extends CommandRunner {
constructor(
private readonly logger: Logger,
private readonly priceRmqHandlerService: PriceRmqHandlerService,
) {
super()
}
async run(inputs: string[], options?: CommandOptions): Promise<void> {
if (options?.data) {
this.runWithData(inputs, options?.data);
} else {
this.runWithNone()
}
process.exit(0)
}
@Option({
flags: '-d, --data json',
description: 'A JSON data parser',
})
parseJson(val: string): Object {
return JSON.parse(val);
}
runWithData(param: string[], option: string): void {
console.log("Running with data...")
}
runWithNone(): void {
console.log("Running...")
}
}
Expected behavior
because we are importing the main module in main-cli.ts
like this:
async function bootstrap() {
await CommandFactory.run(AppModule, ['warn', 'error']);
}
should do the DI automatically!
Package
-
nest-commander
-
nest-commander-schematics
-
nest-commander-testing
Package version
3.11.0
Node.js version
16
In which operating systems have you tested?
- macOS
- Windows
- Linux
Other
No response
There is documentation for it. And here's the API docs too
More than likely, one of the providers you are injecting is REQUEST
scoped, which is what caused the error to trigger. If I had to guess without a reproduction, I would say it's the logger.
I created the module for the command and imported it into the AppModule like this:
@RequestModule({
imports: [SharedModule],
providers: [
EcomProductEventsHandleCommand,
Logger,
PriceRmqHandlerService
],
requestObject: { headers: { Authorization: 'Bearer token' } }
})
export class PriceCommandModule {}
but still, it's giving me the same error
Then please provide a minimum reproduction repository (Git repository/StackBlitz/CodeSandbox project).
why reproductions are required
StackBlitz
Sure! Here we go. you can run it like this npm run command-nest:dev ecom-product-events-handle
https://stackblitz.com/edit/nestjs-typescript-starter-cvtmuu
Explicitly setting the scope to Scope.REQUEST
messes up the possibility of using the @RequestModule()
due to how Nest then treats the provider. What @RequestModule()
is doing is creating a local REQUEST
provider that is explicitly Scope.DEFAULT
so that Nest's automatic resolution of REQUEST
goes to the local definition and it becomes default scoped. But if the @Injectable({ scope: Scope.REQUEST })
is set, then that provider will always be REQUEST
scoped, even if none of the providers inside of it are, which causes the error to come forth. Remove that setting in your RequestService
and everything should work