FX_Sektor
FX_Sektor

Reputation: 1460

Use @ngx-translate in standalone components in Angular 17

I use standalone components in Angular 17. When I used module architecture, I didn't have this problem. I added it to import in AppModule and it works good.

imports: [
 TranslateModule.forRoot(loader)
],

But if I add TranslateModule.forRoot(loader) in standalone components

@Component({
 selector: 'app-main-work-space',
 standalone: true,
 imports: [
  // @ts-ignore
  TranslateModule.forRoot(loader)
 ],
 templateUrl: './main-work-space.component.html',
 styleUrl: './main-work-space.component.scss'
})

In result I have this mistake.

✘ [ERROR] TS-992012: 'imports' contains a ModuleWithProviders value, likely the result of a 'Module.forRoot()'-style call. These calls are not used to configure components and are not valid in standalone component imports - consider importing them in the application bootstrap instead.

I try add @ts-ignore but it doesn't help.

How can I fix it?

Upvotes: 15

Views: 19150

Answers (3)

Andreas Löw
Andreas Löw

Reputation: 1041

How to set up an app is explained in the ngx-translate documentation: https://ngx-translate.org/getting-started/installation/ - both for modules and stand alone components.

Upvotes: 0

Maulik Shah
Maulik Shah

Reputation: 31

//app.config.ts
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideAnimations } from '@angular/platform-browser/animations';
import { HttpBackend, HttpClient, HttpClientModule, provideHttpClient } from '@angular/common/http';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';

export const provideTranslation = () => ({
  defaultLanguage: 'en',
  loader: {
    provide: TranslateLoader,
    useFactory: HttpLoaderFactory,
    deps: [HttpClient],
  },
});

export function HttpLoaderFactory(http: HttpClient) {
  return  new  TranslateHttpLoader(http, './assets/i18n/', '.json');
}
export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes),provideAnimations(),provideHttpClient(),importProvidersFrom(HttpClientModule), importProvidersFrom([TranslateModule.forRoot(provideTranslation())
  ]),],
};
//particular compo
import { TranslateModule, TranslateService } from '@ngx-translate/core';
@Component({
  selector: 'app-home',
  standalone: true,
  imports: [TranslateModule]
})constructor(
   public translate: TranslateService
  ) {}

this.translate.setDefaultLang('en'); //ngonint

Upvotes: 3

Naren Murali
Naren Murali

Reputation: 56002

I think you missed the importProvidersFrom wrapper for translation module, please find below working example along with extra sample code, to help you resolve your problem!

import { Component, importProvidersFrom } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { CommonModule } from '@angular/common';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppModule } from './app/app.module';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClient, HttpClientModule } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import 'zone.js';

// AoT requires an exported function for factories
export function HttpLoaderFactory(httpClient: HttpClient) {
  return new TranslateHttpLoader(httpClient);
}

@Component({
  selector: 'app-root',
  imports: [CommonModule, TranslateModule],
  standalone: true,
  template: `
    <div>
      <h2>{{ 'HOME.TITLE' | translate }}</h2>
      <label>
        {{ 'HOME.SELECT' | translate }}
        <select #langSelect (change)="translate.use(langSelect.value)">
          <option *ngFor="let lang of translate.getLangs()" [value]="lang" [selected]="lang === translate.currentLang">{{ lang }}</option>
        </select>
      </label>
    </div>
  `,
})
export class AppComponent {
  constructor(public translate: TranslateService) {
    translate.addLangs(['en', 'fr']);
    translate.setDefaultLang('en');

    const browserLang = translate.getBrowserLang();
    translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
  }
}

bootstrapApplication(AppComponent, {
  providers: [
    provideHttpClient(),
    importProvidersFrom(
      TranslateModule.forRoot({
        loader: {
          provide: TranslateLoader,
          useFactory: HttpLoaderFactory,
          deps: [HttpClient],
        },
      })
    ),
  ],
});

stackblitz

Stackblitz for reference not by me

Upvotes: 26

Related Questions