如何在Angular应用程序启动之前获取提供程序数据

如何在Angular应用程序启动之前获取提供程序数据,angular,angular-module,Angular,Angular Module,我的目标是从AppConfigService异步获取“clientId”,并在应用程序启动之前将其用作“GoogleLoginProvider”函数的“clientId” 我可以把它放在一个环境变量中,但在我的特定情况下,它不是一个选项 我用的是角度8 import { APP_INITIALIZER } from '@angular/core'; export function getGoogleClientId(appConfigService: AppConfigService) {

我的目标是从AppConfigService异步获取“clientId”,并在应用程序启动之前将其用作“GoogleLoginProvider”函数的“clientId”

我可以把它放在一个环境变量中,但在我的特定情况下,它不是一个选项

我用的是角度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 {}
从'@angular/core'导入{APP_INITIALIZER};
导出函数getGoogleClientId(appConfigService:appConfigService){
return()=>appConfigService.getGoogleClientId().toPromise()。然后((clientId)=>{
//服务在此处可靠地返回clientId
});
}
const getGoogleId:提供程序={
提供:应用程序初始化器,
useFactory:getGoogleClientId,
deps:[AppConfigService],
多:真的
}
@NGD模块({
供应商:[
{
提供:“SocialAuthServiceConfig”,
使用价值:{
奥洛金:错,
供应商:[{
id:GoogleLoginProvider.PROVIDER\u id,

提供者:新的GoogleLoginProvider(clientId),//您的问题是使用
useValue
注入对象,但需要使用
useFactory
根据运行时之前不可用的信息创建可更改的依赖值,该信息允许依赖项(API服务、配置服务等)

然后我建议修改您目前正在使用的库(
angularx social login
),以允许您想要的行为

然而,我正在阅读库代码,我意识到他们接受一个对象和一个承诺

因此,我创建了一个示例来处理promise并从服务器(API)获取配置

app.module.ts

导出函数AppConfigServiceFactory(
configService:AppConfigService
):()=>无效{
返回async()=>await configService.load();
}
@NGD模块({
导入:[BrowserModule、FormsModule、SocialInModule、HttpClientModule],
声明:[AppComponent,HelloComponent],
引导:[AppComponent],
供应商:[
{
提供:应用程序初始化器,
useFactory:AppConfigServiceFactory,
deps:[AppConfigService],
多:真的
},
{
提供:“SocialAuthServiceConfig”,
useValue:新承诺(异步解析=>{
//等待,直到加载应用程序配置服务
const config=await AppConfigService.configFetched();
决心({
奥洛金:错,
供应商:[
{
id:GoogleLoginProvider.PROVIDER\u id,
提供者:新的Google登录提供者(config.googleClientId)
}
]
}作为SocialAuthServiceConfig);
})
}
]
})
导出类AppModule{}
app.config.service

导出类AppConfigService{
静态配置:AppConfig | null=null;
构造函数(私有api:ApiService){}

静态configFetched():Promise

您好,可以帮您吗?@sohaieb我想我已经在使用此解决方案获取clientId。我的问题是,一旦我有了clientId,我该如何将其放入GoogleLoginProvider?以下来源如何:?在本例中,您可以为您的clientId注入http请求,并从apiFactory方法获取结果。@sohaieb I think此解释将我置于相同的情况。此解释说明如何动态添加类,而不是提供程序本身或提供程序的一部分。如果你查看我的代码,你会发现我没有添加类。我需要在注入提供程序或启动应用程序之前添加一个id a提供程序。我认为这是可行的,但它给出了t他的错误是“缺少必需的参数‘client_id’”,但仅当应用程序首次启动时本地存储中没有任何内容。据我所知,“provide:“SocialAuthServiceConfig”行在“AppConfigServiceFactory”之前运行返回。这也发生在您的stackblitz代码中。我明白了,但与我解释的方式相同。此库使用
useValue
为对象提供google密钥id。正确的方法是使用工厂提供值。我们可以尝试使用另一种方法来处理我们面临的异步问题。但是可能是一个有点糟糕的解决方案。但是,我编辑并更改了行为以使用
useValue
,并处理了我们遇到的异步问题。我尝试使用useFactory,但我无法使其正常工作。我明白你所说的有点糟糕是什么意思,但可能在我们的情况下它会正常工作。我刚刚实现了你的解决方案,我认为它是正确的工作,谢谢!