angularangular-ui-routerangular-httpclientangular-resolver

Loading data before AppComponent.ngOnInit is called


In my Angular 8 project, I have a UserService that requests the current User from the server using HttpClient and asynchronously assigns the response to its public user field. I inject a UserService into AppComponent and in its ngOnInit I copy this.userService.user into its own user field, which is bound to the content of a span defined in its HTML template file. In order to force Angular finish loading the User before ngOnInit is called, I implemented the Resolve<User> interface in UserService and set it as the resolver of the root route ("").

My problem is that when the application is started, AppComponent.ngOnInit is called before the router is activated and the resolver loads the User from the server, so AppComponent cannot display the loaded User in its HTML. Is it possible to load data before the bootstrapped component (AppComponent) is loaded, that is, before its ngOnInit method is called?


Solution

  • You can do it with APP_INITIALIZER, a function that will be executed before an application is initialized

    https://angular.io/api/core/APP_INITIALIZER

    In your app.module.ts

    export function initializeConfig(initService: InitService) {
      const x = (): Promise<any> => {
        return initService.Init();
      };
      return x;
    }
    
    @NgModule({
      ...
      providers: [
        InitService,
        {
          provide: APP_INITIALIZER,
          useFactory: initializeConfig,
          deps: [InitService],
          multi: true
        },
      ],
      ...
    })
    

    init.service.ts

    @Injectable()
    export class InitService {
    
      constructor(private service: YourService) {
      }
    
      Init() {
        return new Promise<void>((resolve, reject) => {
          this.service.loadDataBeforeBootstrap.then( () => {
            resolve();
          }).catch( error => {
            reject(error);
          });
        });
      }
    }