How to run a service when the app starts in Angular 2

前端 未结 4 1124
暗喜
暗喜 2020-12-12 15:50

I created a service SocketService, basically it initializes the socket to let the app listen on the port. This service also interacts with some components.

/

4条回答
  •  醉梦人生
    2020-12-12 16:01

    Stuart's answer points in the right direction, but it's not easy to find information on APP_INITIALIZER. The short version is you can use it to run initialization code before any of your other application code runs. I searched for a while and found explanations here and here, which I will summarize in case they disappear from the web.

    APP_INITIALIZER is defined in angular/core. You include it in your app.module.ts like this.

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

    APP_INITIALIZER is an OpaqueToken (or an InjectionToken since Angular 4) that references the ApplicationInitStatus service. ApplicationInitStatus is a multi provider. It supports multiple dependencies and you can use it in your providers list multiple times. It is used like this.

    @NgModule({
      providers: [
        DictionaryService,
        {
          provide: APP_INITIALIZER,
          useFactory: (ds: DictionaryService) => () => return ds.load(),
          deps: [DictionaryService],
          multi: true
        }]
    })
    export class AppModule { }
    

    This provider declaration tells the ApplicationInitStatus class to run the DictionaryService.load() method. load() returns a promise and ApplicationInitStatus blocks the app startup until the promise resolves. The load() function is defined like this.

    load(): Promise {
      return this.dataService.getDiscardReasons()
      .toPromise()
      .then(
        data => {
          this.dictionaries.set("DISCARD_REASONS",data);
        }
      )
    }
    

    Set up like that the dictionary gets loaded first and the other parts of the app can safely depend on it.

    Edit: Be aware that this will increase the up-front load time for you app by however long the load() method takes. If you want to avoid that you could use a resolver on your route instead.

提交回复
热议问题