Nest: [Question] Best approach to inject Services to Decorators

Created on 25 Nov 2017  路  10Comments  路  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[ ] Bug report
[ ] Feature request
[X] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior


I don't know if it's the best approach. If I'm wrong, please, tell me directly a better alternative.

I have a Service to work with Mongoose, with a readOne() method
The Service needs also one @Inject.

@Component()
export class CompaniesService {
  constructor(
    @Inject(config.company.providers.mongodb) private readonly companyModel: Model<CompanyModel>,
  ) { }

  async readOne(hash: string, options = {}): Promise<CompanyModel> {
    const populate = this.getPopulate();

    return await this.companyModel
      .findOne({ hash })
      .populate(populate);
  }

I created a Decorator @company() that find the param and return the model.

import { createRouteParamDecorator } from '@nestjs/common';
import { Request } from 'express';
import { CompaniesService } from '../services/companies.service';


export const Company = createRouteParamDecorator(
  async (param: string = 'company', req: Request) => {
    const company = req.params[param];
   return await companiesService.readOne(company);
  }
);

But I don't know how to do to inject the CompaniesService and use it here directly.

PS: The code isn't perfect, but reproduce the problem.

All 10 comments

Hi @gelito,
You should use a middleware or interceptor instead. Regardless of chosen way, attach the company to the request object. Then grab this property in the decorator factory. 馃檪

Thanks, @kamilmysliwiec, also for your rapid responses. But I try to use an interceptor and have an "order issue"

It's it correct?

  @Get(':company')
  @UseInterceptors(CompanyInterceptor)
  findOne(@Company() company: CompanyModel): CompanyModel {

If I use it, the problem is that @Company() decorator runs before @UseInterceptors(CompanyInterceptor) interceptor so I can use it. (I try at controller scope, also)

I'm doing something wrong??

Thanks a lot!

PS: I'm working trying to create a Nest Skeleton for all our new projects, I'll try to open it as soon as I have something "stable"

@gelito ahh that's true, my mistake. Let's use middleware instead 馃檪

Ok, but then, it's correct that decorators run before Interceptors? (I'll try to move to middleware, thx again)

@gelito yep, interceptors have to run after pipes, and custom decorators are applied before pipes (thanks to that it's possible to run pipes for custom decorators too)

Understood @kamilmysliwiec. As I told you, I wanna prepare a skeleton and show it to you, to receive some feedback.

If it works fine, I'll try to use in all our new projects, and, of course, become a sponsor! ;-)

@gelito I suppose it may interest you - I'm working on the global scope feature, so you could use guards/interceptors without importing module everywhere. 馃檪

Opened by accident 馃槄

Sound good! But, for me, it isn't a problem, I'm used to working with Angular and use modules imports everywhere.

For me, is just the opposed, is stranger use elements (like decorators) outside modules, in Angular, if it's out of a module, it doesn't exist ;-)

If I can help with something, just tell me.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings