Nestjs - Dynamic Modules - Injecting MODULE_OPTIONS_TOKEN into pipe

62 Views Asked by At

UPDATE: Read further down, I managed to find a proper solution for the problem.

Current behavior

I've created a dynamic module, like it was explained in the documentation by using a ConfigurableModuleBuilder and ConfigurableModuleClass

I'm getting this error when trying to inject the configuration token into a pipe:

Nest can't resolve dependencies of the ProcessImagePipe (?). Please make sure that the argument CONFIGURABLE_MODULE_OPTIONS[02271392a116315423ae3] at index [0] is available in the AppModule 

image.module-definitions.ts

export interface ImageModuleOptions {
  size: string;
}

import { ConfigurableModuleBuilder } from '@nestjs/common';

export const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
  new ConfigurableModuleBuilder<ImageModuleOptions>().build();

image.module.ts

import { Module } from '@nestjs/common';
import { ProcessImagePipe } from './process-image.pipe';
import { ConfigurableModuleClass } from './image.module-definitions';
import { ImageService } from './image.service';

@Module({
  providers: [ProcessImagePipe, ImageService],
  exports: [ProcessImagePipe, ImageService],
})
export class ImageModule extends ConfigurableModuleClass {}

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ImageModule } from './image/image.module';

@Module({
  imports: [
    ImageModule.register({
      size: 'large',
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

app.controller.ts

import { Controller, Get, UsePipes } from '@nestjs/common';
import { AppService } from './app.service';
import { ProcessImagePipe } from './image/process-image.pipe';
import { ImageService } from './image/image.service';

@Controller()
export class AppController {
  constructor(
    private readonly appService: AppService,
    private readonly imageService: ImageService,
  ) {}

  @Get()
  @UsePipes(ProcessImagePipe)
  getHello(): string {
    this.imageService.log();
    return this.appService.getHello();
  }
}

That being said, I was perfectly fine injecting the same token in image.service.ts and it works without any errors. It's just when I try to inject it in the pipe.

What works here is if I inject ImageService, which already has MODULE_OPTIONS_TOKEN injected... All works... no errors.

Does any one now if this is a desired behavior? Why wouldn't we want to inject tokens in the Pipe directly?

Minimum reproduction code

https://stackblitz.com/edit/nestjs-typescript-starter-t3bgqu

Solution

I decided to test something wile writing this question and I have managed to solve the problem due to the help of @mwieczorek answer: https://stackoverflow.com/a/76836161/1145107

I did exactly that, I exported MODULE_OPTIONS_TOKEN from the Image module

@Module({
  imports: [
    MulterModule.register({
      storage: memoryStorage(),
    }),
  ],
  providers: [ImageUploadMulterConfigService, ImageUploadService, ImageUploadPipe],
  exports: [ImageUploadService, ImageUploadPipe, MODULE_OPTIONS_TOKEN], // added MODULE_OPTIONS_TOKEN into the export
})

I will just leave this here and hopefully it will help someone else. BR

I expected to have access to injected token inside a pipe.

In the context of the provided code: I expect to see the output of:

console.log('Pipe:', this.options);
0

There are 0 best solutions below