I am creating an angular library that has a root-level service class that references document
. I'd like to add SSR support, but of course document
is not defined in SSR context. It seems that Angular will allow me to dependency inject document
into my service with the DOCUMENT injection token.
So now my service looks like.
import { DOCUMENT } from '@angular/common';
class MyService {
private config: MyConfig;
constructor(
config: MyConfig,
@Inject(DOCUMENT) private document: Document,
) {
this.config = config;
}
}
My question is this: where does document
get injected into my service? My module definition now looks like this, but I know this is not correct because document
is undefined at the callsite.
class MyModule {
static forRoot(config: MyConfig): ModuleWithProviders<MyModule> {
return {
ngModule: MyModule,
useValue: new MyService(
config,
document, // causes ReferenceError with SSR
),
};
}
}
Instead of manually instantiating the service, I can let Angular do it. It will handle injecting document
into the service. Update the module forRoot
definition like so:
export class MyModule {
static forRoot(config: MyConfig): ModuleWithProviders<MyModule> {
return {
ngModule: MyModule,
providers: [
{ provide: 'MyConfig', useValue: config },
MyService, // Angular will automatically inject DOCUMENT and the provided config
],
};
}
}
Both parameters will be injected. The MyService
signature should be updated like so:
import { DOCUMENT } from '@angular/common';
class MyService {
private config: MyConfig;
constructor(
@Inject('MyConfig') config: MyConfig,
@Inject(DOCUMENT) private document: Document,
) {
this.config = config;
}
}