Jay
Jay

Reputation: 604

Access Service variable in AppModule in Angular

I am implementing ngx-google-analytics in my Angular 10 app, but this module requires GA tracking code to be implemented this way:

NgxGoogleAnalyticsModule.forRoot(environment.ga)

Instead of environment variable or hardcoded code. I am looking to bring it from the database using shared service and then access that variable here. But the same in not achievable in appmodule.

As suggested by @Nayan, I tried this solution:

How to inject an service into module in my case?

like this:

export class AppModule { 
  constructor(private pubService: PubService) {
    console.log(this.pubService.StoreData);
    gcCode = this.pubService.StoreData['accessCodes'].filter(res => {
      res.codeName === 'gccode'
    }).codeValue;
  }
}

But in my case I already use

{ provide: APP_INITIALIZER, useFactory: initializeApp, deps: [AppInitService], multi: true},

to initiaze the service and what is happening the constructor is getting loaded prior to the service which actually brings data from the database.

Should I leave initializing the service this way? or Is there another way to do so?

Tried using constructor with Promise and observables both but as soon as I go live, api call takes time and app get loaded before this. I can use timeout but I don't want to.

export class AppModule { 
  constructor(private http: HttpClient) {
    // this.GetData().subscribe(res => {
    //   gcCode = res.filter(d => d.codeName == 'gccode')[0].codeValue;
    // });
    this.GetData();
  }

  GetData() {
    const url = (environment.apiURL+ '/api/pub/GetCodes');
    const promise = this.http.get(url).toPromise();
    promise.then((res: Array<any>) => {
      gcCode = res.filter(d => d.codeName == 'gccode')[0].codeValue;
    }).catch((error)=> {
      console.log(error);
    })
  }
}

Upvotes: 1

Views: 1704

Answers (1)

Sergey
Sergey

Reputation: 7682

You could use a manual approach. Your angular app is bootstrapped from main.ts using this code

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

Until bootstrapModule is called your Angular app is not initialized. You can easily put your logic here.

Like

fetch('api/path')
  .then(res => res.json())
  // Here you need to use any static prop or some global variable
  // because there is no DI yet
  .then(({key}) => MyService.key = key)
  // Bootstrap app when the key was fetched
  .then(() => 
    platformBrowserDynamic()
      .bootstrapModule(AppModule)
  )
  .catch(err => console.error(err));

Then use the fetched key in your module.

APP_INITIALIZER would never work as services resolve after module imports were resolved.

Upvotes: 2

Related Questions