I have an Angular 9 (9.1.4) project and there is a custom factory provider for BASE_URL (the project is based on .NET Core Angular template)
// main.ts
export function getBaseUrl() {
return document.getElementsByTagName('base')[0].href;
}
const providers = [
{ provide: 'BASE_URL', useFactory: getBaseUrl, deps: [] }
];
platformBrowserDynamic(providers).bootstrapModule(AppModule)
.catch(err => console.error(err));
If I want to use the BASE_URL in a class, its super easy, I can just ask for it to be injected in the constructor
export class SomeService {
constructor(
private _httpClient: HttpClient,
@Inject('BASE_URL') private _baseUrl: string // here we go
) { }
and it works as expected. So far so good...
I recently added an APP_INITIALIZER to the app, so I can load some configuration from server up-front. This is done by registering a provider with factory function, into which dependencies can also be injected.
However, the simple approach using @Inject does not work there for some reason:
// app.module.ts
@NgModule({
// other stuff
providers: [
SomeService, // here the @Inject works
{
provide: APP_INITIALIZER,
useFactory: (httpClient: HttpClient, @Inject('BASE_URL') baseUrl: string) => {
// httpClient is OK, but baseUrl is undefined
// app init implementation
},
deps: [HttpClient],
multi: true
}],
because baseUrl is undefined during runtime.
The only way I could get it to work was to inject the Injector from @angular/core:
{
provide: APP_INITIALIZER,
useFactory: (httpClient: HttpClient, injector: Injector) => {
cont baseUrl = injector.get('BASE_URL'); // works, but deprecated
// app init implementation
},
deps: [HttpClient, Injector],
multi: true
}
but there the problem is the deprecation warning on get method (deprecated since v4.0.0).
What's the proper way to get such factory injection working?