angular: AOT - function calls are not supported with Module.forRoot

I’m submitting a … (check one with “x”)

[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior When AOT compiling my project, it throws the following error: Calling function 'PanelModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function. Event though I have no function/lambda functions on my PanelModule file.

Expected behavior It should continue compilation instead of breaking with a normal Module file.

Minimal reproduction of the problem with instructions

  • Have 2 Angular 2 projects

app.module.ts

import { NgModule } from "@angular/core";
import { APP_BASE_HREF } from "@angular/common";
import { BrowserModule, Title } from "@angular/platform-browser";

// Providers
import { URL_BASE } from "./config";
import { CARBON_PROVIDERS } from "angular2-carbonldp/boot";
import { CARBON_SERVICES_PROVIDERS } from "angular2-carbonldp/services";
import { routing, appRoutingProviders } from "./app.routing";
// Components
import { AppComponent } from "./app.component";
import { LoginView } from "./login/login.view";
// Modules
import { PanelModule } from "carbonldp-panel/panel.module";

@NgModule( {
    imports: [
        BrowserModule,
        routing,
        PanelModule.forRoot(),     <---- This line causes the issue
    ],
    declarations: [
        AppComponent,
        LoginView
    ],
    providers: [
        {
            provide: APP_BASE_HREF,
            useValue: URL_BASE
        },
        CARBON_PROVIDERS,
        CARBON_SERVICES_PROVIDERS,
        appRoutingProviders,
        Title,
    ],
    bootstrap: [ AppComponent ],
} )
export class AppModule {}

PanelModule

// Imports 
@NgModule( {
    imports: [
        CommonModule,
        RouterModule,
        SemanticModule,
        DirectivesModule,
        FormsModule
    ],
    declarations: [
        HeaderComponent,
	...
        PaginatorComponent,
    ],
    exports: [
        HeaderComponent,
	...
        PaginatorComponent,
    ],
    providers: []
} )

export class PanelModule {
    static forRoot():ModuleWithProviders {
        return {
            ngModule: PanelModule,
                providers: [ HeaderService, SidebarService, RouterService, MyAppsSidebarService, ErrorsAreaService ]
        };
    }
}

With that configuration, every time I try to AOT compile the project it returns the error mentioned above, but, as you can see, I have no lambda function in my PanelModule forRoot file. If I comment that line (PanelModule.forRoot(),) it continues compilation but I need that line to work.

What is the motivation / use case for changing the behavior? The AOT compilation should work because the files are AOT compliant.

Please tell us about your environment: OS X Sierra.

  • Angular version: 2.0.X @angular@2.4.7 @angular/compiler-cli@2.4.8 Webpack@2.2.1

  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] all

  • Language: [all | TypeScript X.X | ES6/7 | ES5] Typescript@2.1.6

  • Node (for AoT issues): node --version =
    v6.2.0

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 69
  • Comments: 40 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I have the same issue with Angular 4.0.1 and webpack, AoT is a nightmare to configure. I can’t build my app with ngx-bootstrap and ngx-translate.

Angular is really starting to get in my nerves.

@tytskyi I used InjectionToken and now I’m receiving this error (always with qdouble’s starter) :

“ERROR in Error encountered resolving symbol values statically. Calling function ‘InjectionToken’, function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol KEYBOARD_CONFIGURATION in /Users/ks89/git/angular-webpack2-starter-demo-with-angular-modal-gallery/node_modules/angular-modal-gallery/src/modal-gallery.module.ts, resolving symbol ModalGalleryModule.forRoot in /Users/ks89/git/angular-webpack2-starter-demo-with-angular-modal-gallery/node_modules/angular-modal-gallery/src/modal-gallery.module.ts, resolving symbol AppModule in /Users/ks89/git/angular-webpack2-starter-demo-with-angular-modal-gallery/src/app/app.module.ts, resolving symbol AppModule in /Users/ks89/git/angular-webpack2-starter-demo-with-angular-modal-gallery/src/app/app.module.ts”

This is my code:

export const KEYBOARD_CONFIGURATION = new InjectionToken<KeyboardServiceConfig>('KEYBOARD_CONFIGURATION');

@NgModule({
  imports: [ CommonModule ],
  declarations: [ AngularModalGalleryComponent, UpperButtonsComponent, GalleryComponent, DIRECTIVES ],
  exports: [ AngularModalGalleryComponent ]
})
export class ModalGalleryModule {
  static forRoot(config?: KeyboardServiceConfig): ModuleWithProviders {
    return {
      ngModule: ModalGalleryModule,
      providers: [
        {
          provide: KeyboardService,
          useFactory: setupKeyboardService,
          deps: [ KEYBOARD_CONFIGURATION ]
        },
        {
          provide: KEYBOARD_CONFIGURATION,
          useValue: config ? config : {}
        }
      ]
    };
  }
}

export function setupKeyboardService(injector: KeyboardServiceConfig) {
  return new KeyboardService(injector);
}

I tried with angular version 4.0.1 and have the same issue

As I see, this issue has been reported initially on Feb 24, 2017 . Today is the 13th of February, 2018.

@andreimcristof Please note that there has never been a valid repro provided in the entire thread, and most of them are just obvious symlink issue that has nothing to do within this repo.

same here… seems like it’s just a blanket error that is thrown when 1 of the 20 “AOT don’ts” are present in your application. The other one i see is [your]Module is not an ngModule if you don’t have a forRoot().

I’m really hoping for better linting or build errors as this is a pain to triage.

Bug Report

  • bug report I cannot understand why all issues are closed but it got me annoyed to the death… Wasted whole day on this and still cannot understand why this code is not working
@NgModule({
    imports: [CommonModule]
})
export class StoreModule {
    static provideStore(): ModuleWithProviders {
        return {
            ngModule: StoreModule,
            providers: [ added some providers]
        };
    }     
}

throwing an error:

"Calling function 'SotreModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule"

I compared it with RouterModule in .ts and .js all the same. Tried to many of work arounds and nothing. In dev mode all works fine, when this code is added stright to project it works fine too, but when exported as a separate package - BAM - nothing!

Anybody?

For example RouterModule:

@NgModule({declarations: ROUTER_DIRECTIVES, exports: ROUTER_DIRECTIVES})
export class RouterModule {
  constructor(@Optional() @Inject(ROUTER_FORROOT_GUARD) guard: any, @Optional() router: Router) {}
  static forChild(routes: Routes): ModuleWithProviders {
    return {ngModule: RouterModule, providers: [provideRoutes(routes)]};
  }
}

If this thing will not be resolved I will not have any other way just to drop Angular support and stay only in react since this issue with ngc aot is very old.

More than that - when compiling AOT with webpack all works fine, just after upgrading to Angular 5.0.0 ngc-weback plugin is not working any more.

here is complete code of ng-state.module.ts:

import { Inject, Injector, ModuleWithProviders, NgModule, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Dispatcher } from './services/dispatcher';
import { Router } from '@angular/router';
import { RouterState } from './state/router-state';
import { ServiceLocator } from './helpers/service-locator';
import { State } from './state/state';
import { StateHistory } from './state/history';
import { StateHistoryComponent } from './state/state-history';
import { Store } from './store/store';

export const INITIAL_STATE = new InjectionToken('INITIAL_STATE');
export const COLLECT_HISTORY = new InjectionToken('COLLECT_HISTORY');
export const STORE_HISTORY_ITEMS = new InjectionToken('STORE_HISTORY_ITEMS');
export const IS_PROD = new InjectionToken('IS_PROD');

export function stateFactory(initialState) {
    return new State(initialState);
}

export function storeFactory(state: State<any>) {
    return new Store(state);
}

export function historyFactory(store: Store<any>) {
    return new StateHistory(store);
}

export function routerStateFactory(store: Store<any>, router: Router) {
    return new RouterState(store, router);
}

@NgModule({
    imports: [CommonModule],
    declarations: [StateHistoryComponent],
    exports: [StateHistoryComponent]
})
export class StoreModule {
    static provideStore(initialState: any, isProd?: boolean, collectHistory?: boolean, storeHistoryItems?: number): ModuleWithProviders {
        return {
            ngModule: StoreModule,
            providers: [
                { provide: STORE_HISTORY_ITEMS, useValue: storeHistoryItems },
                { provide: COLLECT_HISTORY, useValue: collectHistory },
                { provide: INITIAL_STATE, useValue: initialState },
                { provide: IS_PROD, useValue: isProd },
                { provide: State, useFactory: stateFactory, deps: [INITIAL_STATE] },
                { provide: Store, useFactory: storeFactory, deps: [State] },
                { provide: StateHistory, useFactory: historyFactory, deps: [Store, INITIAL_STATE] },
                { provide: RouterState, useFactory: routerStateFactory, deps: [Store, Router] },
                Dispatcher
            ]
        };
    }

    constructor(
        injector: Injector,
        stateHistory: StateHistory,
        routerState: RouterState,
        @Inject(INITIAL_STATE) initialState: any,
        @Inject(STORE_HISTORY_ITEMS) storeHistoryItems: any,
        @Inject(COLLECT_HISTORY) collectHistory: any,
        @Inject(IS_PROD) isProd: any
    ) {
        if (storeHistoryItems !== undefined) {
            StateHistory.collectHistory = collectHistory;
        }

        if (collectHistory !== undefined) {
            StateHistory.storeHistoryItems = storeHistoryItems;
        }

        ServiceLocator.injector = injector;
        stateHistory.init(initialState);
        routerState.init();

        if (!isProd) {
            (<any>window).state = StateHistory;
        }
    }
}

In my forRoot I was declaring a variable. Removing that solved the issue.

@tytskyi I tried and now It seems ok. I changed the order, downgraded npm from 5.x.x to 3.x.x to use yarn with qdouble’s starter and now It seems ok.

With npm I having the same issue again.

I should open an issue on that repository. Probably it’s not a problem caused by Angular itself.

Thank u for your support.

我的终于可用了。 参考 https://www.angular.cn/guide/singleton-services forRoot直接是return语句的话就可用。forRoot如果中间有别的语句就会报错。

please enable function and object

@andreimcristof … ah OK, but you should use an exported function … like the following pattern:

export function appConfigServiceFactory(config: AppConfig): () => void {
	return () => config.load();
}
@NgModule({
	...
	providers: [
		AppConfig,
		{
			provide: APP_INITIALIZER,
			useFactory: appConfigServiceFactory,
			deps: [AppConfig],
			multi: true
		},
		...
	],
	bootstrap: [AppComponent]
})
export class AppModule {}

Hi, I have the same error. Working fine without aot, throwing the following error with ng build --aot

Error during template compile of ‘AppModule’. Function calls are not supported in decorators but ‘[provider_here]’ was called.

This is after I made a class that implements FactoryProvider from angularcore, But production needs aot. This provider is intended to just run a function on APP_INITIALIZER to fetch the user config - basic stuff which, again, works when building without aot.

As I see, this issue has been reported initially on Feb 24, 2017 . Today is the 13th of February, 2018. With all due respect, are we waiting for Elon Musk to reach Mars before we actually do prioritize investigating this? This is a dealbreaker for production, should it not receive a higher prio?

@Ks89 could you try to reorder providers so that KEYBOARD_CONFIGURATION is first provided, then used as a dependency?

Note: if your ModalGalleryModule is served like linked package (using npm link) you might want to try this solution: https://github.com/angular/angular-cli/issues/3854#issuecomment-274344771 (add this in main project, not the library)

@mlc-mlapis your suggestion of using an exported named function works, but shouldn’t this be part of the documentation somewhere? The documentation for the FactoryProvider simply states “A function to invoke to create a value for this token.”, but there is no mention of it having to be a named and exported function… And the error message isn’t exactly clear either.

FWIW I had this issue and did not understand it because my feature libraries appeared to be identical to others (eg: ngrx) that the AoT compiler did not complain about. As in:

  imports: [
    MyFeatureModule.forRoot(), // <----- FAILED
    EffectsModule.forRoot([
      ControlEffects,
      HeadsUpEffects,
      PartnerEffects
    ]),
    RouterModule.forRoot(ROUTES, { useHash: true }), // <----- WORKS
    StoreRouterConnectingModule,
    StoreModule.forRoot(reducers) // <----- WORKS
  ],

I discovered I had not been building my libraries correctly. I had not been emitting *.metadata.json files. Once I changed my tsconfig.json appropriately, my AoT issues went away.

{
  "angularCompilerOptions": {
    "genDir": "./dist",
    "skipMetadataEmit": false, // <------- WAS PREVIOUSLY true
    "skipTemplateCodegen": true
  },
  ...
}

@andreimcristof No, I’m a normal user as well.

This thread has been filled with all different kinds of questions, like all people reporting an undefined is not a function error, but they’re never refer to the same thing. It’s not possible to investigate “this” as “this” does not exist, but only “these”.

For your case, there’re known design limits for static metadata collecting, your case is not yet supported, please try solution provided by @mlc-mlapis .

I’m currently facing the same issue as @ericmackrodt … Needed to work with Angular Universal and added ngx-bootstrap into my project, after which webpack throws up: ERROR in Error encountered resolving symbol values statically. Calling function ‘Ng2BootstrapModule’, function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule in …