#Importing service empties dependency injection

25 messages · Page 1 of 1 (latest)

crimson girder
#

`@RabbitConsumer()
export class BuyerConsumer {
constructor(
private readonly ondcService: OndcService,
private readonly coreService: CoreService,
private readonly participantService: ParticipantService,
) {
console.log(participantService); // This works fine
}

@RabbitHandler('queue_name')
async helloWorld({}: DTO) {
    console.log(this.participantService); // This does not work -> participantService = undefined
}

}`

I have created a wrapper around @Controller (named @RabbitConsumer), it works absolutely fine until I import participantService in the BuyerConsumer.

As soon as I pass the ParticipantService to BuyerConsumer constructor, all the three service become empty. I start getting following error:
[Nest] 239 - 01/28/2024, 6:52:20 AM ERROR [AmqpService] TypeError: Cannot read properties of undefined (reading 'getProducts')

I can share the implementation of AmqpService as well. But, it just uses nestjs discovery service to fetch all the dependencies and calls the method based on few conditions.

obtuse kraken
#

Is ParticipantService by chance REQUEST scoped?I'm wondering if that's causing an issue here

crimson girder
#

No, It's not.

obtuse kraken
#

It doesn't inject anything that is?

crimson girder
#

`@Injectable()
export class ParticipantService {
constructor(
@InjectModel('Network Participants')
private readonly networkParticipants: Model<NetworkParticipantDocument>,
) {}

async createNetworkParticipant() {}
}`

obtuse kraken
#

And your db isn 't request scoped?

crimson girder
#

No, it isn't. However I am not really sure if mongoose has internally set the Model to be REQUEST scoped.

obtuse kraken
#

Models shouldn't be by default.

#

Can you share that AmqpService?

crimson girder
#

Sure

#

https://gist.github.com/BhupenPal/31091a9b82a726692aba3c39b5bd6d23

This is the complete implementation.
On line 83 this.connectToRabbitMq(); It triggers this method, which then creates

  1. Connection with RabbitMq
  2. Creates a channel
  3. Set up a Dead Letter Exchange
  4. Creates a routing by reading the custom decorators (@RabbitConsumer and @RabbitHandler)
  5. Create queues by reading the args from @RabbitHandler
  6. And it then starts listening to the messages (I guess this is the part we'll be most concerned about) - Line 349
obtuse kraken
#

Where is this getProducts method?

#

398/399?

#

Which would mean 388, which would depend on the value of queue?

crimson girder
#

It's inside coreService, but the that doesn't matter. All the imported services are undefined.

crimson girder
crimson girder
# obtuse kraken Which would mean 388, which would depend on the value of `queue`?

Yes, it does.

This is the value of queueHandler from line 388 when participantService is not imported:
{ consumerInstance: BuyerConsumer { ondcService: OndcService { envService: [EnvService], httpService: [HttpService], ondcUtilService: OndcUtilService {}, ONDC_REGISTRY_URL: 'SOME_URL', ONDC_GATEWAY_URL: 'SOME_OTHER_URL' }, coreService: CoreService { httpService: [HttpService] } }, handlerIdentifier: 'BuyerConsumer:searchOndcGateway', methodName: 'searchOndcGateway', routingKey: 'on_search' }

And this is the value when partcipantService is imported as dep:
{ consumerInstance: BuyerConsumer {}, handlerIdentifier: 'BuyerConsumer:searchOndcGateway', methodName: 'searchOndcGateway', routingKey: 'on_search' }

obtuse kraken
#

Interesting. Any chance you can provide a reproduction?

crimson girder
#

Definitely. The project has started I can share a minimal reproduction with a private repo.

#

I hope that works.

obtuse kraken
#

Does it have a docker-compose and is it minimal?

crimson girder
#

Yes it does have docker compose file and the source code is very small as of now. Still I'll try to remove all the unnecessary bits and share it with you.

merry current
crimson girder
crimson girder
#

@obtuse kraken I can confirm that if I remove the mongoose model from constructor of ParticipantService, things work as expected.

// This is causing the issue
@Injectable() export class ParticipantService { constructor( @InjectModel('Network Participants') private readonly networkParticipants: Model<NetworkParticipantDocument>, ) {} }

// Whereas this works fine
@Injectable() export class ParticipantService { constructor() {} }