TommyF
TommyF

Reputation: 7150

Ensuring Async Service Initialization Is Complete?

I'm using an injectable angular service to provide a Date throughout my application.
This Date value is dependant on a http.get() request to the server.

constructor(...)
{
    this.http.get(...).subscribe(r => { this.foo = r; });
}

public getFoo() : Date
{
    return Bar.dateFrom(this.foo);
}

Is there any way I can ensure the request is completed and this.foo is populated before the service is made available to the components?
I understand that I could return an Observable<Date> instead and .subscribe() everywhere, but that would make the code in many places throughout the application more complex and less readable only to cover one extreme case / race condition.

Is there any other way to ensure we wait initially for the request to come back? The rest of the application can't to anything without it anyways, so I wouldn't mind it to be synchronous here...

Upvotes: 0

Views: 192

Answers (2)

TommyF
TommyF

Reputation: 7150

Turns out the correct way to do this is to include the following in app.module.ts:

export function initConfig(foo: MyImportantService)
{
      return () =>
      {
        return foo.load();
      };
}

@NgModule({
...
   providers:
        [
        ...
        MyImportantService,
        { provide: APP_INITIALIZER, useFactory: initConfig, deps: [MyImportantService], multi: true }
        ...
        ]

and have your service implement a load method like:

public load() : Promise<any>
{
  this.http.get(...)
    .map((res) => res.json())
    .toPromise()
    .then((r) => {
       this.importantVariable = r;
     });
}

This way the APP_INITIALIZER will wait for the Promise to resolve before loading the application and you can return the variable from the service directly without having to go through an Observable.

Upvotes: 1

Dheeraj Kumar
Dheeraj Kumar

Reputation: 4175

In your http call,

 this.http.get(...).subscribe(
r => { this.foo = r; },
(error)=> console.log(error),
()=> // call completed. Do something);

In third parameter of subscribe, your http call is completed, and here you can write code for what you wish to do after call is completed.

Upvotes: 0

Related Questions