angular multiple APP_INITIALIZER that depend on each other

后端 未结 2 1345
长发绾君心
长发绾君心 2021-01-12 19:52

Background: I need to perform couple of initial checks during the application start up (1) read angular app config from ./assets/conf

相关标签:
2条回答
  • 2021-01-12 20:18

    I don't think you actually need an initializer in your case. You just have a value that other services depend on. The problem in your code is that you have an async value and try to expose it as a sync value.

    I think your problems would be solved if you would just expose the config as an Observable and "await" it where it's needed. The benefits are that the application loads as much as it can until the config requests are done.

    For example the shareReplay(1) operator will keep in memory the item and will defer the HTTP request until it's actually needed:

    export class ConfigService {
    
      configData$ = this.httpClient.get<{config1:string}>('./assets/config.json').pipe(shareReplay(1));
    
      constructor(private httpClient: HttpClient) { }
    }
    

    Now your 2nd service can await the configData from the 1st service. Or just transform it via observable piping and expose it further as an observable to defer everything until it's actually needed.

    @Injectable({
      providedIn: 'root'
    })
    export class SettingsService {
    
      settingsData$ = this.configService.configData$.pipe(
        map(c => c.config1 + '...and config service dependent action'),
        shareReplay(1), // also keep the value in memory maybe?
      );
    
      constructor(
        private httpClient: HttpClient,
        private configService: ConfigService
        ) { }
    }
    
    export class HelloComponent implements OnInit {
    
      @Input() name: string;
    
      dataFromConfigSvc: Observable<string>;
      constructor(private configService: ConfigService) { }
    
      ngOnInit() {
        // you could either use async pipe in the template or subscribe here and get the value
        this.dataFromConfigSvc = this.configService.configData$.pipe(map(c => c.config1));
      }
    
    }
    
    0 讨论(0)
  • 2021-01-12 20:20

    just use

    useFactory: (appConfigSvc: ConfigService,settingsService:SettingsService) => {
            return () => {
              return appConfigSvc.loadConfig().then(()=>{
                return settingsService.loadConfig()
              });
            };
          }
    

    See your forked code in stackblitz

    0 讨论(0)
提交回复
热议问题