Reputation: 2834
I'm using the package ngx-cookieconsent
which imports the module as:
const cookieConfig: NgcCookieConsentConfig = {
"cookie": {
"domain": "localhost"
},
...
"theme": "block",
"content": {
"policy": "Cookie Policy"
}
};
...
@NgModule({
imports: [
NgcCookieConsentModule.forRoot(cookieConfig)
]
However, the domain property on the config will be set at runtime and so I can't have this defined as a constant. To get round this I have done the following:
Created a ConfigurationService
that gets the config and stores it:
@Injectable()
export class ConfigurationService {
private configuration: IServerConfiguration;
constructor(private http: HttpClient, @Inject('BASE_URL') private baseUrl: string) { }
loadConfig() {
return this.http.get<IServerConfiguration>(this.baseUrl + 'Configuration')
.pipe(
tap(config => {
this.configuration = <IServerConfiguration>(config);
})
)
.toPromise();
}
public domain(): string {
return this.configuration.domain;
}
}
And this is set up as an APP_INITIALIZER
so that the config is called first:
export function loadConfiguration(configService: ConfigurationService) {
return () => configService.loadConfig();
}
...
providers: [
ConfigurationService,
{
provide: APP_INITIALIZER,
useFactory: loadConfiguration,
multi: true,
deps: [ConfigurationService]
}],
And then have created a class to create my cookieConsentOptions object using the config:
@Injectable()
export class CookieConstentService {
cookieDomain: string;
constructor(configService: ConfigurationService) {
this.cookieDomain = configService.domain();
}
get cookieConstentOptions(): NgcCookieConsentConfig {
return {
"cookie": {
"domain": this.cookieDomain
},
"position": "top-right",
"content": {
"message": "This website uses cookies to ensure you get the best experience on our website."
}
};
}
Issue
I've got the dependency set up between the configService and the CookieConstentService so that I only create the the cookie options when I have the config values.
However, I am unsure how to pass a dynamic value to the .forRoot()
of a module. I should be able to do cookieConsentService.cookieConstentOptions()
to get the object but I'm not sure where to instantiate this to be used in he module import. It takes a dependency so can't just create a new instance myself.
Any ideas how I effectively inject a method into a 3rd party module's forRoot()
?
Thanks
Upvotes: 8
Views: 6403
Reputation: 2834
After posting this question I learnt that the object passed into the forRoot()
method is essentially a singleton, so if I set any values before it gets initialised then it will use this. The way I implemented this was:
import { NgcCookieConsentConfig } from "ngx-cookieconsent";
export const cookieConsentOptions: NgcCookieConsentConfig =
{
"cookie": {
"domain": "not-set"
},
"position": "bottom-right",
"theme": "block",
"palette": {
"popup": {
"background": "#df1010",
"text": "#ffffff",
"link": "#ffffff"
},
"button": {
"background": "#ffffff",
"text": "#000000",
"border": "transparent"
}
},
"type": "info",
"content": {
"message": "This website uses cookies to ensure you get the best experience on our website.",
"dismiss": "Got it!",
"deny": "Refuse cookies",
"link": "Learn more",
"href": "/cookie-policy",
"policy": "Cookie Policy",
"target": "_self"
}
};
Add an APP_INITIALIZER
to the appModule which injects the NgcCookieConsentConfig
object. This will pass in the object created above:
...
{
provide: APP_INITIALIZER,
useFactory: cookieConfigFactory,
deps: [HttpClient, NgcCookieConsentConfig, ConfigurationService],
multi: true
},
...
export function cookieConfigFactory(http: HttpClient, config: NgcCookieConsentConfig, configService: ConfigurationService) {
return () => configService.loadConfig().then(x => config.cookie.domain = x.domain)
}
I'm getting the value for the cookie domain from a custom config service hence why it's being injected in, yours might be different.
NgcCookieConsentModule.forRoot(cookieConsentOptions)
Upvotes: 3