Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJS blocking call

Tags:

angular

rxjs

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)
        );
like image 851
Pankaj Kapare Avatar asked Nov 26 '25 08:11

Pankaj Kapare


1 Answers

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:

    • How to defer Main component's initialization of dependent components so that some promises may get resolved
  • 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:

    • How to pass parameters rendered from backend to angular2 bootstrap method
  • 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:

    • https://github.com/angular/angular/issues/9047
like image 155
Thierry Templier Avatar answered Dec 02 '25 05:12

Thierry Templier