Open monsieurPaon opened 3 years ago
use
{ provide: 'googleTagManagerId', useFactory: googleTagManagerFactory, deps: [AppConfig] },
export function googleTagManagerFactory(config: AppConfig) {
return config.analytics.googleTagManagerId;
}
What do you meen with 'AppConfig' ?
What do you meen with 'AppConfig' ?
AppConfig - you app configuration with googleTagManagerId For example:
AppModule -> providers
{
provide: APP_INITIALIZER,
useFactory: AppConfigurationFactory,
deps: [AppConfig],
multi: true,
}
export function AppConfigurationFactory(config: AppConfig) {
return () => config.init();
}
@Injectable({
providedIn: 'root',
})
export class AppConfig {
googleTagManagerId: string;
constructor(private httpClient: HttpClient) {}
ensureInit(): Promise<AppConfig> {
return new Promise((r) => {
this.httpClient
.get('/config.json', { responseType: 'text' })
.toPromise()
.then((res) => {
const data = JSON.parse(res);
this.googleTagManagerId = data.googleTagManagerId;
r(this);
});
});
}
}
Ho dorry okey i understand. I have try this before but i don't understand how you link the return of the function to the tag manager module. I'm already doing something similar with an other module but in deps of the provider i can call the conf injectionToken.
Error: Google tag manager ID not provided.
{
provide: APP_INITIALIZER,
useFactory: agmConfigFactory,
deps: [HttpClient, LAZY_MAPS_API_CONFIG],
multi: true
},
{
provide: APP_INITIALIZER,
useFactory: AppConfigurationFactory,
deps: [HttpClient, AppConfig],
multi: true,
},
{
provide: HTTP_INTERCEPTORS,
useClass: RequestInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule {
}
export function AppConfigurationFactory(config: AppConfig): any {
return () => config.ensureInit();
}
export function HttpLoaderFactory(http: HttpClient): any {
return new TranslateHttpLoader(http, '../assets/locales/', '.json');
}```
Is there a way to load this module or pass it the GTM Id after the app is fully initialized?
I think the @ancifer response is the right way, but i still lock on my error.
@monsieurPaon All code. App config init run APP_INITIALIZER. After run googleTagManagerId. I hope I helped.
@Injectable({
providedIn: 'root',
})
export class AppConfig {
googleTagManagerId: string;
constructor(private httpClient: HttpClient) {}
init(): Promise<AppConfig> {
return new Promise((r) => {
this.httpClient
.get<AppConfig>('/assets/config.json')
.toPromise()
.then((response: AppConfig) => {
Object.assign(this, response);
r(this);
});
});
}
}
@NgModule({
declarations: [AppComponent],
imports: [
GoogleTagManagerModule
],
providers: [
AppConfig,
{
provide: APP_INITIALIZER,
useFactory: AppConfigurationFactory,
deps: [AppConfig],
multi: true,
},
{ provide: 'googleTagManagerId', useFactory: GoogleTagManagerId, deps: [AppConfig] },
],
bootstrap: [AppComponent],
})
export class AppModule {}
export function AppConfigurationFactory(appConfig: AppConfig) {
return () => appConfig.init();
}
function GoogleTagManagerId(appConfig: AppConfig) {
return appConfig.googleTagManagerId;
}
config.json in assets
{
googleTagManagerId: "YOU GOOGLE TAG MANAGER ID"
}
I've also tried the approach from @ancifer but it doesn't work for me. The googleTagManagerId
factory completes before the APP_INITIALIZER
promise has resolved, because of the time taken to fetch config.json
.
Although Angular waits for APP_INITIALIZER
promises to resolve before loading components, it doesn't wait before loading other providers, so they are loaded in parallel.
So I think that rules out using this library with a config that is loaded using APP_INITIALIZER
. The only solution would be to load the config in main.ts
, before boostrapping the application.
Hi !
I'm working on projects who need to setup different GTM ID in each environnement. The variable comme from an API call and cannot be setup in the env files.
I have try to do, something like that:
`import {map} from 'rxjs/operators'; import {API_PUBLIC} from '../../../environments/environment'; import {HttpClient} from '@angular/common/http'; import {GoogleTagManagerConfig} from 'angular-google-tag-manager';
export function googleTagManagerConfigFactory(http: HttpClient, gtConf: GoogleTagManagerConfig) { return () => http.get<{ gtmTag: string }>(API_PUBLIC + '/config').pipe( map(response => { if (gtConf) { gtConf.id = response.gtmTag; return response.gtmTag; } }) ).toPromise(); }`
providers: [ {provide: GoogleTagManagerConf, useFactory: googleTagManagerConfigFactory} ]
But i'm facing with this error => ERROR in ./src/app/app.module.ts 123:31-51 "export 'GoogleTagManagerConf' was not found in 'angular-google-tag-manager'
Do you have a solution to lazy load the angularTagManagerModule ?