0

I've found other posts on this subject, but my issues aren't the same. I can avoid this issue entirely by turning off AOT compilation.

I'm using Angular 11.

In code that had been working before Angular 11, I had some providers defined like this:

  providers: [
    HighlighterService,
    SignInService,
    { provide: AUTHENTICATOR, useClass: AuthenticationService },
    { provide: NETWORK_ERROR_INTERCEPTOR_CONFIG, useFactory: getNetworkErrorInterceptorConfig },
    { provide: HTTP_INTERCEPTORS, useClass: UnauthorizedNetworkInterceptor, multi: true },
  ],

With AOT in Angular 11, this provider setup fails with:

Function calls are not supported in decorators but 'InjectionToken' was called in 'AUTHENTICATOR'

The supposed solution I've found for this issue by researching the above error is this:

@NgModule({
  declarations: [
    AppComponent...
  ],
  imports: [
    BrowserModule...
    MyOtherModule // <--- New problem crops up here
  ],
  bootstrap: [
    AppComponent
  ]
})
export class AppModule {
  static forRoot(): ModuleWithProviders<any> {
    return {
      ngModule: AppModule,
      providers: [
        HighlighterService,
        SignInService,
        { provide: AUTHENTICATOR, useClass: AuthenticationService },
        { provide: NETWORK_ERROR_INTERCEPTOR_CONFIG, useFactory: getNetworkErrorInterceptorConfig },
        { provide: HTTP_INTERCEPTORS, useClass: UnauthorizedNetworkInterceptor, multi: true },
      ],
    };
  }
}

The above changes, however, just spawn a new problem. A module that I was able to import before without any difficultly now produces this run-time error:

Error: Unexpected value 'MyOtherModule in C:/...' imported by the module 'AppModule in C:...'. Please add a @NgModule annotation.

But MyOtherModule does have @NgModule annotation. Always had it, and never before was there any such error about @NgModule annotation not being there.

The only thing I can think of is that something about the order in which Angular is trying to resolve modules references MyModule before the @NgModule annotation has been executed on the class.

If that's the problem, I have no idea how to solve it.

If that's not the problem, I'm even more mystified about how to get my code working properly with AOT.

UPDATE

I understand the problem better now, but I still don't know what to do about it.

The @NgModule annotation adds this static member to a module class:

export class MyModule {
  public static ngModuleDef = defineNgModule({
    type: MyModule ,
    imports: [...my imports...],
    declarations: [...my declarations...],
    bootstrap: [...my bootstrap component, if any...]
  });

In the Angular code base, I found a place where a function is called getNgModuleDef(moduleType), and the above error about the missing @NgModule annotation is thrown if no module definition is found.

From this I can conclude that MyOtherModule is being referenced before the annotation has had a chance to act on the MyOtherModule and inject this static ngModuleDef member, and therefore my module has not been defined as a valid module.

This seems like a nasty Catch-22 to me.

Is there someway to delay the instantiation of my main AppModule until I'm sure MyOtherModule has been fully loaded and defined by @NgModule?

kshetline
  • 12,547
  • 4
  • 37
  • 73

0 Answers0