Angular 2 Make and Handle Ajax Request For Config Before Module Is BootStrapped

307 views Asked by At

I'm using Angular 2.3.

I'd like to make an ajax request to load data into my Configuration Service, and only allow the Configuration Service to be injected into other components and services once the ajax response has been received and processed.

I've tried two techniques so far, neither is working:

In the first instance, I use this technique in the app module:

providers: [
  Config2Service,
  {
    provide: APP_INITIALIZER,
    deps: [ Config2Service ],
    multi: true,
    useFactory: (configService: Config2Service) => {
      return () => configService.initialize();
    }
  }
]

In this example, initialize() returns a promise which the factory wraps in a function before returning that function. This was the only combination that works. The following do not work: (1) returning config.initialize itself. (2) returning the result of calling configservice.initialize().

Don't get me wrong, the configService's initialize function is called early on, but the promise returned does not get waited upon; the app bootstraps then fails when components try to access the configuration data in the config service. Sometime later, the config data turns up and is processed properly, but by then its too late, the app has crashed.

In the second case, I removed the above, and tried to do this:

let providers = [
    {
      provide: Http, useFactory: (backend: XHRBackend, options: RequestOptions) => {
        return new Http(backend, options);
      },
      deps: [XHRBackend, RequestOptions]
    },
    BrowserXhr,
    ConfigService,
    XHRBackend,
    { provide: RequestOptions, useClass: BaseRequestOptions },
    { provide: ResponseOptions, useClass: BaseResponseOptions },
    { provide: XSRFStrategy, useValue: new CookieXSRFStrategy() }
];

let configService: ConfigService = ReflectiveInjector.resolveAndCreate(providers).get(ConfigService);

configService.initialize()
    .then(configData => {
        platformBrowserDynamic().bootstrapModule(MyAccountModule.factory(configService));
    });

The above fails with this error: Unhandled Promise rejection: Cannot read property 'getCookie' of null at CookieXSRFStrategy.configureRequest

In the SO example I got this from, the concrete XSRFStrategy was called NoopCookieXSRFStrategy but I can't find that in the @angular/http folder. Nor can I find HTTP_PROVIDERS from which this code originated I think.

I've you've tried what I'm trying to do, what am I missing?

1

There are 1 answers

0
Paul Samsotha On BEST ANSWER

From my personal experience, I was never able to get the APP_INITIALIZER working the way I needed it to either. I couldn't find any examples that worked for me. So I just ran with what you are trying to do in the second attempt. With this though, you need to extend the CookieXSRFStrategy and override the configureRequest. This is where the NoopCookieXSRFStrategy came from.

class NoopCookieXSRFStrategy extends CookieXSRFStrategy {
  configureRequest(request) {
    // noop
  }
}

See complete example