我有2个APP_INITIALIZER提供商......第一个发出HTTP请求来获取环境信息。
第二个使用环境信息来授权用户针对OIDC Authority服务器端点(从环境调用获得)。
看起来,尽管使环境服务成为授权服务的依赖关系,但在环境调用完成之前调用授权服务的APP_INITIALIZER工厂函数。
{ provide: APP_INITIALIZER, multi: true, useFactory: EnvironmentFactory, deps: [] }
{ provide: APP_INITIALIZER, multi: true, useFactory: AuthorizationFactory, deps: [EnvironmentProvider] }
提供给APP_INITIALIZER的两个工厂都是签名:
Factory() { return () => Promise; }
结果是授权呼叫提交到undefined
而不是正确的URL。
我想过将这些工厂结合起来 - 但它们分为两个不同的模块,所以感觉很麻烦。指导赞赏!
答案 0 :(得分:0)
我最终将已解析的EnvironmentProvider注入AuthorizationFactory。
我向EnvironmentProvider添加了一个observable,它随着Authority值的变化而发出。
{ 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)
});
}
我使用ReplaySubject(1)
作为env.Authority $()的来源。这确保了返回的observable总是在AuthorizationFactory订阅时发出(例如,如果在AuthorizationFactory订阅之前解析了Authority)。
任何遇到此问题的人都在想我为什么不使用toPromise()......我认为存在一些问题(我已经提交审核)。 https://github.com/Reactive-Extensions/RxJS/issues/1429