Reputation: 7150
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
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
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