jsverse / transloco

🚀 😍 The internationalization (i18n) library for Angular
https://jsverse.github.io/transloco/
MIT License
2.01k stars 195 forks source link

Why isn't Transloco applying the `inline` prefix and overriding translations? #766

Closed jon9090 closed 6 days ago

jon9090 commented 4 months ago

Is there an existing issue for this?

Which Transloco package(s) are the source of the bug?

Transloco

Current behavior

I created an example using scope. In the example code, there are two components (foo and bar), each with its own translations. The app component toggles between these two components. When a component loads, it should also load its respective translations using the inline prefix (scope).

Each component has its own scope, but they written the same key. It seems that provideTranslocoScope doesn't override the existing inline translations. Why is this happening?

Here's the code:

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import {
  TranslocoDirective,
  provideTransloco,
  provideTranslocoScope,
} from '@jsverse/transloco';
import { of } from 'rxjs';

@Component({
  selector: 'foo',
  standalone: true,
  imports: [TranslocoDirective],
  template: `
    im foo!!
    <ng-container *transloco="let t; prefix: 'inline';">
     <h1>{{ t('title') }}</h1>
    </ng-container>
  `,
  providers: [
    provideTranslocoScope({
      scope: 'inline',
      loader: {
        en: () => Promise.resolve({ title: 'foo title in en' }),
        fr: () => Promise.resolve({ title: 'foo title in fr' }),
      },
    }),
  ],
})
export class Foo {}

@Component({
  selector: 'bar',
  standalone: true,
  imports: [TranslocoDirective],
  template: `
   im bar!!
   <ng-container *transloco="let t; prefix: 'inline';">
    <h1>{{ t('title') }}</h1>
   </ng-container>
  `,
  providers: [
    provideTranslocoScope({
      scope: 'inline',
      loader: {
        en: () => Promise.resolve({ title: 'bar title in en' }),
        fr: () => Promise.resolve({ title: 'bar title in fr' }),
      },
    }),
  ],
})
export class Bar {}

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, Foo, Bar],
  template: `
    im app!
    <foo *ngIf="toggle"></foo>
    <bar *ngIf="!toggle"></bar>

    <button (click)="toggle=!toggle">switch</button>
  `,
})
export class App {
  name = 'Angular';
  toggle = false;
}

bootstrapApplication(App, {
  providers: [
    provideTransloco({
      config: {
        availableLangs: ['en', 'fr'],
      },
      // loader: class implements TranslocoLoader {
      //   getTranslation(lang: string) {
      //     return of(langs[lang]);
      //   }
      // },
    }),
  ],
});

You can view and modify the code on StackBlitz: StackBlitz Example

shaharkazaz commented 4 months ago

@jon9090 Can you please share why would you name these two scopes with the same name?

The scope isn't overridden because Transloco has an internal cache, and by giving the same name to the scope, Transloco assumes that this is the same translation.

shaharkazaz commented 2 months ago

@jon9090 In case you missed my previous comment ☝️

shaharkazaz commented 6 days ago

Feel free to reopen.