javascriptangulartypescriptpromiseapp-initializer

Angular provideAppInitializer is initialized after ngOnInit


I have in my ApplicationConfig provider

provideAppInitializer(() => {
  inject(AppConfigService)
})

In component MainPageComponent I have ngOnInit(), which geting data from backend every refresh.

 ngOnInit() {
this.loginService.getHi().subscribe({
  next: result => {
    this.text = result;
    void this._router.navigate(['mainPage'])
  },
  error: err => {
    void this._router.navigate(['login'])
    console.log("Login failed", err);
  },
  complete: () => {
    console.log('Login process completed ' + localStorage.getItem("token"));
  }
})

problem is Global app initialization is after ngOnInit() is called, how to avoid it?

AppConfigService

export class AppConfigService {
  private appConfig!: AppConfig;

  constructor(private readonly http: HttpClient) {
    void this.loadAppConfig();
  }

   loadAppConfig(): Promise<any> {
    return firstValueFrom(this.http.get<AppConfig>('/config/config.json').pipe(tap(data => {
      console.log('my data ' + JSON.stringify(data));
      this.appConfig = data;
    })));
  }

  getBackendBaseUrl(): string {
    return this.appConfig.environment.backendURL;
  }

Solution

  • Since we are triggering the API on the constructor of the service. The app initializer will not wait for the API to complete, you must return the promise, so that once it is resolved the application loads.


    So we execute and return the method inside the provideAppInitializer, so that once the promise load is completed the application will load.

    First we remove the call from the constructor.

    export class AppConfigService {
      private appConfig!: AppConfig;
    
       loadAppConfig(): Promise<any> {
        return firstValueFrom(this.http.get<AppConfig>('/config/config.json').pipe(tap(data => {
          console.log('my data ' + JSON.stringify(data));
          this.appConfig = data;
        })));
      }
    
      getBackendBaseUrl(): string {
        return this.appConfig.environment.backendURL;
      }
    

    Then we return the promise from execution of loadAppConfig.

    provideAppInitializer(() => {
      const appConfigService = inject(AppConfigService);
      return appConfigService.loadAppConfig();
    })