angularangular-aotangular-di

Angular 4 inject console with AOT


This code fails in development mode with Ahead of time compilation.

export function loggerFactory(console, http, device, injector) {
  return environment.production ?
         new LogstashLoggerService(device, injector, http) :
         new ConsoleLoggerService(console);
};

let consoleObj = window.console;

@NgModule({
  imports: [],
  exports: [],
  declarations: [],
  providers: [],
})
export class LoggerModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: LoggerModule,
      providers: [
        {provide: CONSOLE, useValue: consoleObj},
        {
          provide: Logger,
          useFactory: loggerFactory,
          deps: [CONSOLE, HttpInterceptor, DeviceService, Injector]
        }
      ]
    };
  }
}

How can I inject console?


Solution

  • You have to use useFactory for anything you want to inject for AOT. See the changes in bold italic. I added a named injection factory of "Console".

    import { Inject } from '@angular/core';
    
    export function loggerFactory(@Inject('Console') console, http, device, injector) {
      return environment.production ?
             new LogstashLoggerService(device, injector, http) :
             new ConsoleLoggerService(console);
    };
    
    
    export function consoleFactory(): any {
        return console;
    }
    
    
    @NgModule({
      imports: [],
      exports: [],
      declarations: [],
      providers: [],
    })
    export class LoggerModule {
      static forRoot(): ModuleWithProviders {
        return {
          ngModule: LoggerModule,
          providers: [
            { provide: 'Console', useFactory: consoleFactory },
            {
              provide: Logger,
              useFactory: loggerFactory,
              deps: [CONSOLE, HttpInterceptor, DeviceService, Injector]
            }
          ]
        };
      }
    }