Search code examples
nestjstypeorm

NestJS - Inject service into Pipe to fetch from DB


I am trying to inject a service into a PipeTransform class to fetch an entry from DB.

I have tried the solution in this answer but I am getting a different error Inject service into pipe in NestJs

sample.pipe.ts

@Injectable()
export class SamplePipe implements PipeTransform<any> {
  constructor(private readonly sampleService: SampleService) {}

  async transform(value: any, metadata: ArgumentMetadata) {
    const id = parseInt(value, 10);
    let sample: SampleEntiy = await this.sampleService.findOne(id);
    if (!sample) throw new NotFoundException('Sample Not Found');
    return sample;
  }
}

sample.controller.ts

@Controller('sample')
export class SampleController {
  constructor(private readonly sampleService: SampleService) {}

  @Get(':id')
  async findOne(@Param('id', SamplePipe) id: SampleEntiy): Promise<SampleEntiy> {
    return sample;
  }

}

I get the following error at return sample in the controller

Type '<T>(notifier: Observable<any>) => MonoTypeOperatorFunction<T>' is missing the following properties from type 'SampleEntiy': id, value, isActivets(2739)

On forcing it to return using any I get the following response in my browser

function sample(notifier) {
return lift_1.operate(function (source, subscriber) {
var hasValue = false;
var lastValue = null;
source.subscribe(new OperatorSubscriber_1.OperatorSubscriber(subscriber, function (value) {
hasValue = true;
lastValue = value;
}));
var emit = function () {
if (hasValue) {
hasValue = false;
var value = lastValue;
lastValue = null;
subscriber.next(value);
}
};
notifier.subscribe(new OperatorSubscriber_1.OperatorSubscriber(subscriber, emit, noop_1.noop));
});
}

I understand that it is to do with async. The docs say async is supported

First, note that the transform() method is marked as async. This is possible because Nest supports both synchronous and asynchronous pipes. We make this method async because some of the class-validator validations can be async (utilize Promises).

And I am trying something mentioned in the docs:

Another useful transformation case would be to select an existing user entity from the database using an id supplied in the request:

@Get(':id') 
findOne(@Param('id', UserByIdPipe) userEntity:UserEntity) {
  return userEntity; 
} 

Solution

  • You're returning the sample function from the rxjs package here (sic!):

    @Get(':id')
    async findOne(@Param('id', SamplePipe) id: SampleEntiy): Promise<SampleEntiy> {
      return sample;
    }
    

    The parameter is called id, and you probably meant to return it instead, or even better, rename it to sample:

    @Get(':id')
    async findOne(@Param('id', SamplePipe) sample: SampleEntiy): Promise<SampleEntiy> {
      return sample;
    }