Royi Namir
Royi Namir

Reputation: 148554

`APP_INITIALIZER` vs (`platformBrowserDynamic` with `provide`)

I already know that I can postpone an Angular bootstrap until a Promise or Obseravable are resolved.

Example :

app.module.ts

{
  provide: APP_INITIALIZER,
  useFactory: (configService: ConfigurationService) => ()=> configService.load(),
  deps: [ConfigurationService],
  multi: true
}

But i've seen this other approach of using platformBrowserDynamic's providers :

example :

main.ts:

  (function () {
  return new Promise((resolver) => {
    const someData = {...}

    window.setTimeout(() => //simulate ajax data fetch
    {
      resolver(someData );
    }, 1000);
  });
})()
  .then((myData:any) => platformBrowserDynamic([ {provide: 'pbdProvider', useValue: myData  }]).bootstrapModule(...)

Question:

When should I use APP_INITIALIZER vs (platformBrowserDynamic with provide)?

Upvotes: 2

Views: 1036

Answers (2)

hawks
hawks

Reputation: 931

The thing with APP_INITIALIZER that it does not guarantee the bootstrap of lazy loaded modules. For example, if the user loads a lazy loaded path this module will be loaded without waiting for the the requests that APP_INITIALIZER has started.

Thats why the platformBrowserDynamic is preferred when you want to be sure that all the data is fetched. The only downside of this approach can be the blank screen if the request takes too long or not access into angular injection capabilities.

Angular imported modules do not wait for APP_INITIALIZER

Upvotes: 4

Abdullah Alhazmy
Abdullah Alhazmy

Reputation: 627

Using the APP_INITIALIZER

The APP_INITIALIZER from Angular allows you to load things before your app starts. This might fill your needs, Since the APP_INITIALIZER also supports Observables, it got even handier and easier to use.

The problem with this approach is that when you have a module in the imports array which has a forRoot(...) method and you want to pass some data into it, which is loaded in the APP_INITIALIZER you have a chicken-egg-problem. The AppModule needs to gather all modules in the imports array and therefore, also runs the forRoot(...)s, if any, but the info to pass it to forRoot(...)s can only be gathered when the APP_INITIALIZER has been called. But to call this, the forRoot(...) has to have the info first, etc.

Using platformBrowserDynamic()

Angulars platformBrowserDynamic() takes an optional parameter called extraProviders?: StaticProvider[], which we can use to pass extra providers. We can use the Fetch API to load our data, and when it is loaded, bootstrap our application and provide the config. then load the APP_INITIALIZER with ready data that you can use with any provider later.

Upvotes: 3

Related Questions