Your problem is that you're using useValue
to inject an object but you need to use useFactory
to create a changeable, dependent value based on information unavailable before run time which allows dependencies (API service, config service, etc).
Then I suggest modifying the library you're using at this moment (angularx-social-login
) to allow the behavior that you want.
However, I was reading the library code and I realized that they accept an object and a promise!
You can check It here
Hence, I create an example to handle promise and fetch our config from our server (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;
}
}
}
My complete solution is here on stackblitz.