Skip to content

Factory providers are called before APP_INITIALIZER is resolved (before bootstrap) #19448

@shipiak

Description

@shipiak

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x ] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Factory providers are called before APP_INITIALIZER is resolved (before bootstrap).
When using pattern with APP_INITIALIZER to load external configuration, config injection works only with services that are NOT provided by factory.

Expected behavior

Factory provider functions executed after APP_INITIALIZER resolved.

Minimal reproduction of the problem with instructions

export function initConfiguration(configService: ConfigService): Function {
  return () => configService.load(); // makes http request and returns Promise correctly
}

// this is called before bootstrap - before APP_INITIALIZER resolved
export function serviceFactory(configService: ConfigService){
   return new SomeServiceDependentOnConfig(configService);
}

@NgModule({
  imports: [
    //Some imports here.
  ],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
  providers: [
    ConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: initConfiguration,
      deps: [ConfigService],
      multi: true
    },
    {
       // this one does NOT get config injected correctly (json config not yet loaded)
       provide: SomeServiceDependentOnConfig,
       useFactory: serviceFactory,
       deps: [ConfigService]
    },
    {
       // this one does get config injected correctly (json config already loaded)
       provide: SomeOtherServiceDependentOnConfig,
       useClass: SomeOtherServiceDependentOnConfig,
    }
  ]
})
export class AppModule { }


// then 

What is the motivation / use case for changing the behavior?

  1. need to use env config that is passed to te app during deployment (DEV,UAT,PROD) not during the build of the app
  2. therefore using pattern with APP_INITIALIZER and loading env config using http request (json file)
  3. need to use env config values directly in factory function - e.g. if config.value ? return a() : return b()
  4. need to use env config values in services created by factory

PS: Point 1. actually seems to me as kind of a bug itself, as current solution with angular environment config that is being passed to the app during the build is not really environment aware... I always thought that point of environment config is to change behavior of the same build, not that you have to make separate builds for each environment...

Environment


Angular version: 4.2.1


Browser:
- [ x] Chrome (desktop) version XX
- [ x] Chrome (Android) version XX
- [ x] Chrome (iOS) version XX
- [ x] Firefox version XX
- [ x] Safari (desktop) version XX
- [ x] Safari (iOS) version XX
- [ x] IE version XX
- [ x] Edge version XX
 
For Tooling issues:
- Node version: 6.11.1  
- Platform:  

Others:

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: coreIssues related to the framework runtimeneeds reproductionThis issue needs a reproduction in order for the team to investigate further

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions