-1

I'm using ngrx/data 14 and Angular 14. I have built a custom module that I load in my app.module.ts file like so

@NgModule({
  declarations: [
    AppComponent 
  ],
  imports: [
    ...
    AppRoutingModule,
    MyCustomModule,
    ...
  ],
  providers: [
    ...
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

The custom module is defined this way

export function initialize(appService: AppService){
  console.log("in initialize");
 return () => appService.load();
}
...
@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  exports: [
    ...
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initialize,
      deps: [
        AppService
      ],
      multi: true
    },
    ...
  ]
})

export class MyCustomModule { 
  constructor(entityDataService: EntityDataService, myObjectDataService: MyObjectDataService) {
    console.log("called from module");
    entityDataService.registerService('MyObject',  myObjectDataService);
  }
}

The problem is, I notice that the module constructor is run before the "initialize" method (I can see the console.log "called from module" is called before the "in initialize" statement within the "initialize" method. My question is, how or where do I put code that will initialize prior to my module getting instantiated?

Dave
  • 15,639
  • 133
  • 442
  • 830

1 Answers1

0

I noticed APP_INITIALIZER is not initializing before the module and this is happening after Angular version 14 and 14+.

One workaround for this is to get your initial configuration using fetch API. So whatever data you are fetching from the AppService you can get it using fetch API here.

Then call your platformBrowserDynamic Settings once you receive response from the fetch API.

Try this stackblitz example.

import './polyfills';
export interface AppConfig {
  auth: {
    auth0_audience: string,
    auth0_domain: string,
    auth0_client_id: string,
  };
}

import {
  platformBrowserDynamic
} from '@angular/platform-browser-dynamic';


import {
  AppModule
} from './app/app.module';
import {
  InjectionToken
} from '@angular/core';

const APP_CONFIG: InjectionToken < AppConfig > = new InjectionToken < AppConfig > ('Application Configuration');
// Same as App service
fetch('./config.json')
  .then((res) => res.json())
  .then((config) => {
    console.log("Initialize")
    console.log(config)
    // Save this config in window object to access it across application.
    window['config'] = config;
    platformBrowserDynamic([{
      provide: APP_CONFIG,
      useValue: config
    }, ]).bootstrapModule(AppModule).then(ref => {
      // Ensure Angular destroys itself on hot reloads.

      // Otherwise, log the boot error
    }).catch(err => console.error(err));
  });
prathameshk73
  • 1,048
  • 1
  • 5
  • 16
  • I notice you do the "fetch" in your "main.ts" file. How would you then get the APP_CONFIG into an AppService? (The AppService is a dependency of MyObjectDataService, which is passed to the constructor of my custom module) – Dave Dec 03 '22 at 18:10
  • @Dave Just try to save this config in window['config'] variable. You can now access it anywhere. Check I have updated the stackblitz for the same. – prathameshk73 Dec 04 '22 at 07:49
  • You can take the results from the fetch method, and use it along with angular injection tokens. You can pass those tokens into the platformBrowserDynamic method, which you can then @Inject into wherever you need it. – aasukisuki Dec 28 '22 at 03:58