0

In my angular application I am using the APP_INITALIZER and GlobalERRORHandler. my Global Error Handler has a dependency on the a service which handles logging.

export function loadConfig(config: ConfigService) => () => config.load()

@NgModule({
    declarations: [AppComponent],
    imports: [BrowserModule,
        routes,
        FormsModule,
        HttpModule],
    providers: [
        ConfigService,
        {
            provide: APP_INITIALIZER,
            useFactory: loadConfig,
            deps: [ConfigService],
            multi: true
        }, 
    ErrorLoggingService,
{
      provide: ErrorHandler,
      useClass: GlobalErrorHandler,
      deps: [ErrorLoggingService]
    }

    ],
    bootstrap: [AppComponent]
})
export class AppModule {
}

However, my implementation of the ErrorLoggingService is also dependant on the a configService Implementation which get injected by the angular DI.

    @Injectable()
    export class ErrorLoggingService {
      _errorLogAPIUrl: string;
      seen = [];

      constructor(private http: HttpClient, private config: ConfigService) {
        config.load().then(e => (this._errorLogAPIUrl = config.errorLoggingUrl));
      }

      logClientError(error: Error): Observable<any> {

        const convertedObservable = this.http.post<any>(
          error
        );
        convertedObservable.subscribe(e => {});
        return convertedObservable;
      }
}

The definition of my globalerrorhandler implementation is as below.

@Injectable()
export class GlobalErrorHandler extends ErrorHandler {
  constructor(
    private _errorLogService: ErrorLoggingService
  ) {
    super(true);
  }

  handleError(error: any): void {
    this._errorLogService.logClientError(error);
    throw error;
  }

}

However, I am having the issue show up where an error occurs and some of this service has not been hooked up yet because the ErrorHandler code runs before the APP_INITIALIZER run which means I have no config to work with in the errorLogservice.

Is there a way to handle a scenario like this within angular. So that I have my config and also my service at bootup before APP_INITALIZER loads.

I have tried this stackoverflow( Angular: APP_INITIALIZER with GlobalErrorHandler ) answer but it breaks a whole lot of other things such as e2e and angular cli commands.

damola
  • 282
  • 5
  • 18
  • Wouldn't regular `injector.get` recipe for circular dependencies be applicable here, like this one https://stackoverflow.com/questions/46470469/angular-4-3x-dynamic-http-interceptor ? *So that I have my config and also my service at bootup before APP_INITALIZER loads* - no, you will need to fetch them before bootstrapping the app, with Fetch API or another Angular app. – Estus Flask Nov 13 '17 at 08:57
  • I am not sure I follow. I don't think it is a circular dependency issue as the application works fine it is just that the value in the Error Logging service is null when I go on to use it. Or am I missing something. Can you explain a little bit further what you meant by bootstrapping it . I tried using dynamically loading it in my main.ts file but I encountered other error as described above. – damola Nov 13 '17 at 09:32
  • Get the service as `injector.get(ErrorLoggingService)` in `handleError` instead of injecting it in constructor. You can also pre-fetch a config before bootstrapping, like `fetch(...).then(config => { window.config = config; bootstrapModuleFactory(...) }`. I'm not sure if there's a better way to supply provider value than a global that would be compatible with AOT. – Estus Flask Nov 13 '17 at 09:50

0 Answers0