Angular-cli: "Consider replacing the function or lambda with a reference to an exported function" - but it already is exported

Created on 8 Jun 2017  路  7Comments  路  Source: angular/angular-cli

Bug Report or Feature Request (mark with an x)

- [x] bug report -> please search issues before submitting
- [ ] feature request

Versions.

  • @angular/cli: 1.0.0
    node: 6.10.1
    os: win32 x64

  • @angular/cli: 1.0.6
    node: 7.10.0
    os: darwin x64

Repro steps.

  • Create a blank app:

    ng new test-app
    
  • Create a dummy module:

    import { ModuleWithProviders, NgModule } from '@angular/core';
    
    export function foo() { }
    
    @NgModule({
      providers: [],
    })
    export class TestModule {
      static create(): ModuleWithProviders {
        foo();  // note this
    
        return { ngModule: TestModule, providers: [] };
      }
    }
    
  • Add TestModule.create() to your imports array in app.module.ts.

  • Now ng serve. Note the following:

    1. The first time it tries to run, you get the error log below;
    2. If you add a blank line or something to get it to re-run, it works fine;
    3. If you comment out the call to foo and re-start ng serve, it also works fine.

The log given by the failure.

ERROR in Error encountered resolving symbol values statically. Calling function 'TestModule', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function, resolving symbol AppModule in .../src/app/app.module.ts, resolving symbol AppModule in .../src/app/app.module.ts
webpack: Failed to compile.

...but it is an exported function, so which part is it complaining about?

Desired functionality.

We are trying to inject configuration from the environment.ts files into a service within a module, so something like:

export function buildService(config) {
  let service = new OurService();
  service.configure(config);
  return service;
}

...

static withConfig(config): ModuleWithProviders {
  return {
    ngModule: OurModule,
    providers: [
      { provide: OurService, useValue: buildService(config) }
    ],
  }
}

...

imports: [
  ...,
  OurModule.withConfig(environment.config),
]

We tried a few versions (e.g. useFactory, useValue, creating the service directly in OurModule.withConfig), assuming we were doing something wrong, but even with this trivial no-op setup we see the same error.

Mention any other details that might be useful.

We read numerous other related issues, but most seemed to be fixed by replacing anonymous lambdas (e.g. { provide: OurService, useFactory: () => buildService(config) }) with an exported function. In this case, the function we're trying to call is already exported.

2 (required) broken

Most helpful comment

@textbook @aleixmorgadas Has an official solution been decided on this? I am also running into the same issue; made a custom module, and just want to pass in some simple environment variables into the withConfig method of the module.

All 7 comments

This does not appear to be an issue with the CLI, can you please open an issue on the main angular repo or pose this question on a support site, like stackoverflow?

Thanks for looking into this @Brocco; do you have any feel for where the problem is? I opened the issue here because if I clone angular/quickstart and do the same things, the same behaviour doesn't occur.

@textbook have you solved the issue?

The angular works well with useValue: buildService(config), but when I use the cli it crashes with the same error as you posted here.

A work around that I made is use a Factory instead of Value

useValue should be simple raw value, otherwise should be useFactory.
Methods that returns ModuleWithProviders should be simple return statement with no logic inside.

See technical details here: https://gist.github.com/chuckjaz/65dcc2fd5f4f5463e492ed0cb93bca60

See example here (how are configured angular router providers): https://github.com/angular/angular/blob/master/packages/router/src/router_module.ts#L139
(Notice how config is provided as ROUTER_CONFIGURATION and then below ROUTER_CONFIGURATION is used as a dependency for provideLocationStrategy. This is basically your solution.)

Thanks @tytskyi

@textbook @aleixmorgadas Has an official solution been decided on this? I am also running into the same issue; made a custom module, and just want to pass in some simple environment variables into the withConfig method of the module.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings