angulardependency-injectionangular-servicesangular-dependency-injectiontransloco

How to inject a Service inside ApplicationConfig?


How to inject a Service inside ApplicationConfig?

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(appRoutes),
    provideTransloco({
      config: {
        availableLangs: ['en', 'ru', 'kk'],
        defaultLang: LanguageService.getDefaultLanguage(),
        reRenderOnLangChange: true,
        prodMode: !isDevMode(),
      },
      loader: TranslocoHttpLoader,
    }),
  ],
};

Here, I want to use LanguageService

I used:

  1. defaultLang: (new LanguageService).getDefaultLanguage(),
  2. defaultLang: inject(LanguageService).getDefaultLanguage(),

All of them shows injection context error So, is it possible to use Service inside ApplicationConfig?


Solution

  • As far as I know, it is not possible to defer the environment providers initialization until you fetch the data using app_initializer so I fetch the API get the default language and then bootstrap the application after the response has been received.

    export function initializeApp(): Promise<any> {
      // fetch("https://someUrl.com/api/user") // <- place your API here!
      return firstValueFrom(
        of({ defaultLang: 'en' }) // simulate api call
      );
    }
    
    initializeApp().then((data: any) => {
      bootstrapApplication(App, {
        providers: [
          provideHttpClient(),
          provideTransloco({
            config: {
              availableLangs: ['en', 'es'],
              defaultLang: data.defaultLang,
              // Remove this option if your application doesn't support changing language in runtime.
              reRenderOnLangChange: true,
              prodMode: false,
            },
            loader: TranslocoHttpLoader,
          }),
        ],
      });
    });
    

    Full Code:

    import {
      Component,
      APP_INITIALIZER,
      makeEnvironmentProviders,
    } from '@angular/core';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { HttpClient, provideHttpClient } from '@angular/common/http';
    import { provideTransloco, TranslocoModule } from '@jsverse/transloco';
    import { firstValueFrom, tap, of } from 'rxjs';
    import { TranslocoHttpLoader, LanguageService } from './transloco-loader';
    
    @Component({
      selector: 'app-root',
      standalone: true,
      imports: [TranslocoModule],
      template: `
      asdf
      <ng-container *transloco="let t">
          <p>{{ t('home') }}</p>
      </ng-container> 
      `,
    })
    export class App {
      name = 'Angular';
    }
    
    export function initializeApp(): Promise<any> {
      // fetch("https://someUrl.com/api/user") // <- place your API here!
      return firstValueFrom(
        of({ defaultLang: 'en' }) // simulate api call
      );
    }
    
    initializeApp().then((data: any) => {
      bootstrapApplication(App, {
        providers: [
          provideHttpClient(),
          provideTransloco({
            config: {
              availableLangs: ['en', 'es'],
              defaultLang: data.defaultLang,
              // Remove this option if your application doesn't support changing language in runtime.
              reRenderOnLangChange: true,
              prodMode: false,
            },
            loader: TranslocoHttpLoader,
          }),
        ],
      });
    });
    

    Stackblitz Demo