Search code examples
angularng-modulesangular-providers

Angular APP_INITIALIZER deps doesnt work - service is undefined


I am trying to use APP_INITIALIZER to do initial call for env values but for some reason service that have this function is undefined during runInitializers. Function is in our external library. I have tried to do this in library with the function.

Library:

// environmentService is undefined
function loadEnvironmentalValues(environmentService: EnvironmentService): () => Observable<EnvironmentValue> {
  return () => environmentService.getEnv().pipe(tap(() => console.log('ENV LOADED')));
}

@NgModule({
  declarations: [],
  imports: [HttpClientModule, NgxPermissionsModule],
  exports: [],
  providers: [
    EnvironmentService,
    {
      provide: APP_INITIALIZER,
      useFactory: () => loadEnvironmentalValues,
      deps: [EnvironmentService],
      multi: true
    }]
})
export class OurLibraryModule{
  constructor() {
  }
}

After this i tried to do this application that use this library

// again environmentService is undefined
function loadEnvironmentalValues(environmentService: EnvironmentService): () => Observable<EnvironmentValue> {
  console.log('service je ', environmentService, !!environmentService);
  return () => environmentService.getEnv().pipe(tap(() => console.log('ENV LOADED from app')));
}

imports: [
    OurLibraryModule
],
providers: [
    EnvironmentService,
    {
      provide: APP_INITIALIZER,
      useFactory: () => loadEnvironmentalValues,
      deps: [EnvironmentService],
      multi: true
    },

This is service:

@Injectable({
  providedIn: 'root',
})
export class EnvironmentService {
  private readonly environmentValues$: Observable<EnvironmentValue>;

  constructor(private httpClient: HttpClient) {
    this.environmentValues$ = this.getEnvironmentValues().pipe(share());
  }

  getEnv(key?: string): Observable<EnvironmentValue> {
    if (key) {
      return this.environmentValues$.pipe(
        map((environmentConfig: EnvironmentValue) => environmentConfig[key])
      )
    } else {
      return this.environmentValues$;
    }
  }

  private getEnvironmentValues(): Observable<EnvironmentValue> {
    return this.httpClient.get<EnvironmentValue>(CONFIG_PATH).pipe(
      catchError((error: unknown) => {
        // eslint-disable-next-line no-console
        console.log('UNABLE TO LOAD ENVIRONMENT VALUES');
        // eslint-disable-next-line no-console
        console.error(error);
        throw error;
      }));
  }
}

I am missing something? Is there something that i have to do before using APP_INITIALIZER


Solution

  • I think you can look at your code here:

    {
          provide: APP_INITIALIZER,
          useFactory: () => loadEnvironmentalValues,
          deps: [EnvironmentService],
          multi: true
        },
    }
    

    It must be like this: Look at your useFactory

    {
          provide: APP_INITIALIZER,
          useFactory: loadEnvironmentalValues,
          deps: [EnvironmentService],
          multi: true
        },