简体   繁体   中英

NestJS Decorator - Context this is undefined

We are trying to build our own Kafka integration. We capture a reference to the function using the decorator and then are attempting to trigger it somewhere else when a new message is received from Kafka

Decorator:

export const SUBSCRIBER_FN_REF_MAP = new Map();
export const SUBSCRIBER_OBJ_REF_MAP = new Map();

export function SubscribeTo(topic) {
    return (target, propertyKey, descriptor) => {
        const originalMethod = target[propertyKey];
        SUBSCRIBER_FN_REF_MAP.set(topic, originalMethod);
        SUBSCRIBER_OBJ_REF_MAP.set(topic, target);
        return descriptor;
    };
}

When using it in a Service where we inject some Repositories, the context is always undefined:

@Injectable()
export class KafkaEventsListenerService {

  constructor(
    private readonly messageUserRepository: MessageUserRepository
  ) {
  }

  @SubscribeTo(DANCEFLAVORSAPI_USER_CREATED_TOPIC)
  async onUserCreated(payload: string): Promise<void> {
    console.log('[KafkaConsumer receiving ' + DANCEFLAVORSAPI_USER_CREATED_TOPIC + ']: ', payload);

    console.log(await this.messageUserRepository.findAll());

  }

}
@Injectable()
export class MessageUserRepository {
  constructor(
    @InjectRepository(MessageUserEntity)
    private readonly repository: Repository<MessageUserEntity>
  ) {}

  async findAll(): Promise<MessageUserEntity[]>{
    return await this.repository.find();
  }
}

The repository function call results in an error:

Cannot read property 'findAll' of undefined

When i remove the decorator, it works.

Can someone help me please?

Based on the code sample from your decorator it looks like you're trying to capture a reference to the class method and then invoke it somewhere else (outside of the NestJS lifecycle).

Decorators are run immediately, before everything gets bootstrapped in the NestJS Dependency Injection container so constructor arguments to the class won't be resolved or available.

I recommend that you rethink the architecture of your decorator and move things into the onModuleInit of your application to properly discover and bind your Kafka handlers.

I built the @golevelup/nestjs-rabbitmq package which does the same kind of thing you're trying to accomplish here but using rabbitmq instead of Kafka.

The basic steps you should take are:

The @golevelup/nestjs-discovery package makes it really easy to scan all of your providers and their methods to find decorator metadata (disclaimer, I am the author)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM