3

In my application there is angular 2 service lets say "Configuration Service" which returns RxJS Observable sequence. This sequence contains configuration data. On subscribing this sequence it returns data however data returned is asynchronously. In normal scenario asynchronous call may be desired however in one particular case I need to get this configuration data "synchronously" as without that configuration data returned from service execution flow can not continue. Is there any way I can make blocking call with observable sequence so that I can still use this existing configuration service? My code looks something like below:

this.configService.getConfigData()
        .subscribe(
            x=>{                    
                this.ConfigData = x;                    
            },
            e=>console.log(e)
        );
Pankaj Kapare
  • 7,486
  • 5
  • 40
  • 56
  • See also http://stackoverflow.com/questions/37611549/how-to-pass-parameters-rendered-from-backend-to-angular2-bootstrap-method/37611614#37611614 – Günter Zöchbauer Jun 09 '16 at 06:20

1 Answers1

1

There is no way to turn things synchronously.

The approach you could consider is to load configuration data before bootstrapping your application. So they will be there when the application is started.

Here are the different possible approaches:

  • You could bootstrap asynchronously after your request(s) complete(s). Here is a sample:

    var app = platform(BROWSER_PROVIDERS)
      .application([BROWSER_APP_PROVIDERS, appProviders]);
    
    var service = app.injector.get(ConfigService);
    
    service.loadConfig().flatMap((config) => {
      var configProvider = new Provider('config', { useValue: config });
      return app.bootstrap(appComponentType, [ companiesProvider ]);
    }).toPromise();
    

    See this question:

  • I see another approach if you're able to update index.html page (the main entry point) on the server side. Here is a sample:

    <script>
      var params = {"token": "@User.Token", "xxx": "@User.Yyy"};
      System.import('app/main').then((module) => {
        module.main(params);
      });
    </script>
    

    See this question:

  • You could also register an APP_INITIALIZER provider for this:

    provide(APP_INITIALIZER, {
      useFactory: (service:ConfigService) => () => service.loadConfig(), 
      deps:[ConfigService, HTTP_PROVIDERS],
      multi: true}),
    

    See this issue for more details:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • When you say there is no way to run this subscribe block synchronously, I'm getting hopeful. Because, I'm interested in finding this "no" way. Indeed, I'm stuck in a blocking subscribe block. https://stackoverflow.com/q/64801947/958373 – Stephane Nov 14 '20 at 21:24