0

I have an instance variable that I need throughout my application. However it needs to be loaded before it bootstraps the AppModule and I'd like to inject it throughout my application.

This is the function call that I need to execute:

async function load(): Promise<MyConfig> {
   //omitted for brevity
}

And my main.ts looks like this:

platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(err => console.error(err));
  1. Where is the best place to call load()
  2. How would I take that resolved MyConfig from Promise<MyConfig> and inject throughout my Angular app?

2 Answers 2

0

Where is the best place to call load()

You can call load function in the App module. Angular provides a way to achieve it. You can use APP_INITIALIZER. The provided functions are injected at application startup and executed during app initialisation. If any of these functions returns a Promise or an Observable, initialisation does not complete until the Promise is resolved or the Observable is completed.

function initializeApp(): Promise<any> {
  return new Promise((resolve, reject) => {
    // Do some asynchronous stuff
    resolve();
  });
}

@NgModule({
 imports: [BrowserModule],
 declarations: [AppComponent],
 bootstrap: [AppComponent],
 providers: [{
   provide: APP_INITIALIZER,
   useFactory: () => initializeApp,
   multi: true
  }]
 })
export class AppModule {}

How would I take that resolved MyConfig from Promise and inject throughout my Angular app?

Now, this can be done in number of ways, but I would suggest to create a service at the root level to keep the data in one place then you can pass it to the store or save on localStorage whatever fits your case.

Config Service:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
import { map } from 'rxjs/operator/map';

@Injectable()
export class AppConfigService {

  private configData: any;

  constructor(private http: HttpClient) {}

  load() :Promise<any>  {
      const promise = this.http.get('URL').toPromise()
                      .then(data => {
                          return data;
                       });
      return promise;
  }
  // once you get the data set it;
  setConfigData (data) {
       this.configData = data;
  }

  getConfigData (data) {
      return this.configData;
  }
}

In you App.module.ts :

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { AppConfigService } from './services/app-config.service';

export function appInit(appConfigService: AppConfigService) {
  return new Promise((resolve, reject) => {
    // Do some asynchronous stuff
    this.appConfigService.load().then(data=> {
             this.appConfigService.setConfigData(data);
             resolve();
    })
    
  });
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [

  ],
  providers: [AppConfigService,
    {
      provide: APP_INITIALIZER,
      useFactory: appInit,
      multi: true,
      deps: [AppConfigService]
    }],
  bootstrap: [AppComponent]
})
export class AppModule { }
Sign up to request clarification or add additional context in comments.

3 Comments

This looks great! Thank you so much. Is it possible to just skip the AppConfigService part and just inject the variable returned resolved from the load() function?
Yes, you can do it that way it is fine.
toPromise() is now deprecated, is there any other way to do this ?
-1

you might be looking for APP_INITIALIZER

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.