I\'ve got 2 APP_INITIALIZER providers... the first makes an HTTP request to get environment information.
The second uses the environment info to authorize the user agai
I ended up injecting the resolved EnvironmentProvider into the AuthorizationFactory.
I added an observable to the EnvironmentProvider that emits any time the Authority value changes.
{ provide: APP_INITIALIZER, multi: true,
useFactory: EnvironmentFactory, deps: [EnvironmentProvider] }
{ provide: APP_INITIALIZER, multi: true, useFactory: AuthorizationFactory,
deps: [AuthorizationProvider, EnvironmentProvider] }
export function AuthorizationFactory (auth: AuthorizationProvider, env: EnvironmentService) {
return new Promise((resolve, reject) => env.Authority$()
// don't emit until authority provider has a value
.skipWhile(authority => !authority)
// dispatch the auth command to ngrx/store.
.do(() => store.dispatch({ type: 'AuthorizeIdentity' }))
// switch to observe identity state
.switchMap(() => store.select('Identity'))
// don't emit until there is an identity (async authorization complete).
.skipWhile(identity => !identity)
// finish.
.take(1)
.subscribe(resolve, reject)
});
}
I use a ReplaySubject(1)
as the source for env.Authority$(). This ensures that the observable returned always emits upon subscription by the AuthorizationFactory (e.g. if the Authority was resolved prior to the AuthorizationFactory subscribing).
Anyone who comes across this wondering why I'm not using toPromise()... I think there is some issue (I've submitted for review here). https://github.com/Reactive-Extensions/RxJS/issues/1429