如何解决如何在 Angular 应用程序启动之前获取提供者数据
我的目标是从 AppConfigService 异步获取“clientId”,并在应用启动之前将其用作“GoogleLoginProvider”函数的“clientId”。
我可以把它放在一个环境变量中,但在我的特定情况下,它不是一个选项。
我使用的是 Angular 8。
import { APP_INITIALIZER } from '@angular/core';
export function getGoogleClientId(appConfigService: AppConfigService) {
return () => appConfigService.getGoogleClientId().toPromise().then((clientId) => {
// service reliably returns clientId here
});
}
const getGoogleId: Provider = {
provide: APP_INITIALIZER,useFactory: getGoogleClientId,deps: [AppConfigService],multi: true
}
@NgModule({
providers: [
{
provide: 'SocialAuthServiceConfig',useValue: {
autoLogin: false,providers: [{
id: GoogleLoginProvider.PROVIDER_ID,provider: new GoogleLoginProvider(clientId),//<-- How do I get the service's "clientId" here?
}],} as SocialAuthServiceConfig
}
]
})
export class AppModule {}
解决方法
您的问题是您使用 useValue
注入对象,但您需要使用 useFactory
根据运行时之前不可用的信息创建可更改的依赖值,从而允许依赖(API 服务、配置服务等)。
那么我建议修改您此时使用的库 (angularx-social-login
) 以允许您想要的行为。
然而,我正在阅读库代码,我意识到他们接受一个对象和一个承诺!
因此,我创建了一个示例来处理 promise 并从我们的服务器 (API) 中获取我们的配置。
app.module.ts
export function AppConfigServiceFactory(
configService: AppConfigService
): () => void {
return async () => await configService.load();
}
@NgModule({
imports: [BrowserModule,FormsModule,SocialLoginModule,HttpClientModule],declarations: [AppComponent,HelloComponent],bootstrap: [AppComponent],providers: [
{
provide: APP_INITIALIZER,useFactory: AppConfigServiceFactory,deps: [AppConfigService],multi: true
},{
provide: "SocialAuthServiceConfig",useValue: new Promise(async resolve => {
// await until the app config service is loaded
const config = await AppConfigService.configFetched();
resolve({
autoLogin: false,providers: [
{
id: GoogleLoginProvider.PROVIDER_ID,provider: new GoogleLoginProvider(config.googleClientId)
}
]
} as SocialAuthServiceConfig);
})
}
]
})
export class AppModule {}
app.config.service
export class AppConfigService {
static config: AppConfig | null = null;
constructor(private api: ApiService) {}
static configFetched(): Promise<AppConfig> {
return new Promise(async resolve => {
// wait for the app config service is loaded (after 3000 ms)
const sleep = (ms: number) => new Promise(r => setTimeout(r,ms));
const waitFor = async function waitFor(f) {
// check each 500 ms
while (!f()) await sleep(500);
return f();
};
await waitFor(() => AppConfigService?.config);
resolve(AppConfigService.config);
});
}
async load(): Promise<AppConfig> {
try {
// simulating HTTP request to obtain my config
const promise = new Promise<AppConfig>(resolve => {
// after 3000 ms our config will be available
setTimeout(async () => {
const config: AppConfig = await this.api.getConfig().toPromise();
AppConfigService.config = config;
resolve(config);
},3000);
}).then(config => config);
return promise;
} catch (error) {
throw error;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。