0

Before bootstraping my angular app I need to perform an async operation which returns some context for the application. Before starting, I need to init some 3rd party repository with these returned data, and then I'd like to inject this repository into on of my app's services. I'm looking for a proper, clean way of doing it, because the one that I currently have looks a bit hacky for me.

app.module.ts content:

let repo; //this is what i'd like to avoid

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        ReactiveFormsModule
    ],
    providers: [
        {
            provide: SomeService, useFactory: () => new SomeService(repo)
        }
    ],
    entryComponents: [AppComponent]
})
export class AppModule implements DoBootstrap {
    ngDoBootstrap(app: ApplicationRef) {

        //some async operation which returns context data
        setTimeout((data) => {
            repo = Some3rdPartyDatabaseSDK.init(data.token, data.repoConfig)
            app.bootstrap(AppComponent);
        }, 3000);
    }
}

Can it be done better?

5
  • You're looking for APP_INITIALIZER Commented Dec 23, 2019 at 9:25
  • is it required while development or required in production (after build) also? Commented Dec 23, 2019 at 9:58
  • @Plochie in prod. Angular app will be run in iframe, and parent frame will deliver some auth data by posMessage Commented Dec 23, 2019 at 10:15
  • @akn you will need APP_INITIALIZER then as suggested by @yurzui. Commented Dec 23, 2019 at 10:18
  • @Plochie, nope. I have to learn about it first. Answer with example is still welcomed :) Commented Dec 23, 2019 at 14:11

1 Answer 1

1

For this scenarios you should use, APP_INITIALIZER, This function is called when angular app is initialized.

Angular will execute provided function when the app is initialized. Angular will wait for the initialization if the function returns a promise until the promise resolved.

  1. Create AppLoadService in your project
  2. Create initialization method in service. (this method should return promise)
  3. Create function which will refer init method in module.
  4. setup APP_INITIALIZER in providers.

DEMO (Application will initialize after 5s)

app-load.service.ts

@Injectable()
export class AppLoadService {

  repo: any;

  init(): Promise<any> {

    return new Promise((resolve, reject) => {

      console.log('App is yet to initialize');

      setTimeout(() => {
        console.log('App initialized');
        this.repo = 'some value';
        resolve();
      }, 5000);
    });
  }

}

app.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core';

function init_app(appLoadService: AppLoadService) {
    return () => appLoadService.init();
}

@NgModule({
  providers: [
    AppLoadService,
    { provide: APP_INITIALIZER, useFactory: init_app, deps: [AppLoadService], multi: true }
  ]
})
export class AppModule { }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.