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?