Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Tom Wieschalla
    @gastdozent91

    Hey there Transloco-Team,

    we got an Angular-App with an integrated login process (login without translation). We added Transloco's RootModule in our AppModule (like described here) without a default language (because we want the persisted user language to be the default one) -> so Transloco is bootstrapping with his default language 'en'. Additionally after a succesfull login we load the persisted user language from our backend server like described in your recipe "Prefetch the User Language" with the TranslocoService.

    1. Is this the right way to fetch a language during runtime?
    2. After "prefetching" the persisted user language (e.g. 'de') the default language 'en' is loaded too when we use a transloco pipe in a html-file the first time. Is there a possibility to prevent the default-language-loading?
    3. Is there a way to integrate the TranslocoRootModule in another Module (e.g. a RoutingModule which is loaded after the login process successfully pass)?

    thanks in advance!

    Itay Oded
    @itayod
    Hi @gastdozent91
    1. It is about what fit you best, prefetching the user language, means that the transactions will preload before the application is up so all the transactions can be used synchronously.
    2. That happens since you didn't set the default language, if you getting the user's lang from your backend you might need to set it using APP_INITIALIZER.
    3. Not sure how your app is built, but basically there should bee one TranslocoRootModule per application.
    Sravan
    @shravansofts

    Hi
    can someone help how to do the unit testing while using transoloco.translate() in typescript?
    https://ngneat.github.io/transloco/docs/unit-testing this works while using pipe/directive on html dom.
    When I have a utility function like below in my service.:
    public getFormattedCapacity(val: number): string {
    let result: string = "";
    if (typeof val == 'number') {
    if (val >= this.TBYTE) {
    result = (val / this.TBYTE).toFixed(2) + " " + this.transloco.translate('terabyte');
    } else if (val >= this.GBYTE) {
    result = (val / this.GBYTE).toFixed(2) + " " + this.transloco.translate('gigabyte');
    } else if (val >= this.MBYTE) {
    result = (val / this.MBYTE).toFixed(2) + " " + this.transloco.translate('megabyte');
    } else if (val >= this.KBYTE) {
    result = (val / this.KBYTE).toFixed(2) + " " + this.transloco.translate('kilobyte');
    } else if (val >= 0) {
    result = val + " " + this.transloco.translate('byte');
    } else {
    result = this.transloco.translate('notapplicable');
    }
    }
    return result;
    }
    }

    when im writing unit testing:
    it("Should return capacity in terms of KB when call method getFormattedCapacity", () => {
    let value = service.getFormattedCapacity(1024);
    expect(value).toBe("1.00 kilobyte"); // asserting to true. I mean returning key but not value

       expect(value).toBe("1.00 KB");  //Intension/expected assertion behavior
    });

    Here is the beforeeach looks:
    beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
    imports: [
    SharedModule,
    TranslocoTestingModule,
    getTranslocoModule()
    ],
    providers: [MyUtilService,
    GlobalService,
    TranslocoService
    ]
    });
    service = TestBed.inject(MyUtilService);
    }));

    Brian
    @seadonk

    @shravansofts
    The Translate function does not wait for the translations to load. You have to preload them. You can check out the TranslocoPreloadLangsModule, or you can just setActiveLang in your beforeEach and wait for it to actually load. When possible, try to use selectTranslate instead, since it will produce an observable that changes every time the translations are loaded.

    We had a similar situation before, I've quoted the previous thread below.

    @avifox spectator is not necessary, but it really makes everything easier. My examples are below.
    For missing keys, I agree with @shaharkazaz , if you want to check for missing keys, just run transloco-keys-manager find and look for the missing and unused keys. If you wanted it automated, maybe there is a way to parse the output and make it a pass/fail step in your build process.

    i pulled out my setLanguage promise into a function that i can call:

      /** setting the language does not happen immediately. It must first load,
       * then change detection must fire.
       * This method will set the lang, and wait for it to load and detect changes. */
      async function setLang(lang: string) {
        await new Promise(resolve => {
          translocoService.events$.pipe(
            filter((t: TranslocoEvents) => t.type === 'translationLoadSuccess')
          ).subscribe(t => resolve());
          translocoService.setActiveLang(lang);
        }).then(() => spectator.detectChanges());
      }

    here is my beforeEach:

    beforeEach(() => {
        // tests were written for the case that spanish is the default language
        TranslocoConfigProvider.useValue.defaultLang = 'es';
        spectator = createSpectator();
        translocoService = spectator.inject(TranslocoService);
        // set lang here so we can make sure it is loaded before running tests
        setLang('es');
      });

    make sure to also use the TranslocoTestingModule, here's what I used, borrowed from Transloco:

    export const languageMap = {
      en,
      es,
      'i18nTest/en': admin,
      'i18nTest/es': adminSpanish,
      'lazyPage/en': lazy,
      'lazyPage/es': lazySpanish,
      'mf/en': transpilersMessageFormat,
      'mf/es': transpilersMessageFormatSpanish
    };
    
    export function getTranslocoTestModule(config: Partial<TranslocoConfig> = {}) {
      return TranslocoTestingModule.withLangs(
        languageMap,
        {
          availableLangs: ['es', 'en'],
          defaultLang: 'es',
          fallbackLang: 'en',
          ...config
        }
      );
    }
    Shahar Kazaz
    @shaharkazaz

    @shravansofts @brian
    The reason this is working for you while using the directive or pipe is that we take of it behind the scenes, when you use the service it's your responsibility.

    This behavior doesn't make sense while testing, that's why in v2.20.0 we introduced the preloadLangs property in the testing module config, which tells transloco to preload the languages into the service.

    I updated the docs with the property since it was missing and this question was raised several times, even recently: ngneat/transloco#400.

    There is more information regarding this change here.

    Victor Diaz
    @vdiaz1130

    Hello, can you provide a usage example of the upcase customFormatter. https://www.npmjs.com/package/@ngneat/transloco-messageformat

    I tried the example but nothing I've used in the JSON file works: {{itemName | upcase}}, {{itemName, upcase}}, {itemName | upcase}, {itemName, upcase}. I also reversed them (e.g {{upcase itemName}})

    Brian
    @seadonk
    Recently, I noticed that my tests started complaining about missing providers for various constants from TranslocoLocale. Is there something different I need to start doing in my unit tests? For now, I have to provide each one of these for the tests to pass.
    { provide: LOCALE_CURRENCY_MAPPING, useValue: {} },
    { provide: LOCALE_LANG_MAPPING, useValue: {} },
    { provide: LOCALE_DEFAULT_LOCALE, useValue: 'en-US' },
    { provide: LOCALE_CONFIG, useValue: {} },
    { provide: TRANSLOCO_NUMBER_TRANSFORMER, useValue: {} },
    { provide: TRANSLOCO_DATE_TRANSFORMER, useValue: {} }
    Brian
    @seadonk
    thanks @shaharkazaz , the preloadLangs property has already fixed translations in several unit tests for me.
    Itay Oded
    @itayod

    Recently, I noticed that my tests started complaining about missing providers for various constants from TranslocoLocale. Is there something different I need to start doing in my unit tests? For now, I have to provide each one of these for the tests to pass.

    { provide: LOCALE_CURRENCY_MAPPING, useValue: {} },
    { provide: LOCALE_LANG_MAPPING, useValue: {} },
    { provide: LOCALE_DEFAULT_LOCALE, useValue: 'en-US' },
    { provide: LOCALE_CONFIG, useValue: {} },
    { provide: TRANSLOCO_NUMBER_TRANSFORMER, useValue: {} },
    { provide: TRANSLOCO_DATE_TRANSFORMER, useValue: {} }

    What exactly are you testing? it seems redundant to fake all these providers in unit tests ( usually you need to fake just what you are using e.g. pipe, directive, etc... ). I suggest you take a look at spectator as a good practice library for testing, there are many use-cases there that might suit your need.

    Brian
    @seadonk
    @itayod I am using spectator. I am not testing any l10n features, but these errors started appearing in my tests. My app does use translocolocale.
    Sune Radich Vestergaard
    @SuneRadich
    I have a lazy loaded feature module with a scopeloader - but then also an eager loaded module used by the lazy loaded feature. The eager loaded module is a series of ngrx effects that handle opening error modals. So I am not able to add a component level provider, as I only ever dispath an event with the language keys as parameters. Is it possible to add a scope at runtime somehow?
    1 reply
    François
    @GrandSchtroumpf

    Hello, is there a way to use a scope with the translation API ?
    I would like to do something like that inside a lazy route component using the scope "product".

    transloco.translate('product.step.optional');

    The code tries to load it from the root i18n file instead of "product" scope
    I also tried:

    transloco.translate('step.optional', {}, 'product');

    Which extract in the right file, but doesn't use the scope for translation

    6 replies
    Brian
    @seadonk

    I'm having trouble testing anything that uses TranslocoLocale pipes in a service.

    TranslocoLocale pipes in my component templates work correctly in unit tests, but if I inject the pipes in a service, injected in the constructor, they do not work. How should I setup my tests for this?

    In the example below, My service uses the TranslocoDecimalPipe. In my test I get the error:

    NullInjectorError: StaticInjectorError(DynamicTestModule)[L10nTestService -> TranslocoDecimalPipe]: 
      StaticInjectorError(Platform: core)[L10nTestService -> TranslocoDecimalPipe]: 
        NullInjectorError: No provider for TranslocoDecimalPipe!
    import { Injectable } from '@angular/core';
    import { createServiceFactory, SpectatorService } from '@ngneat/spectator/jest';
    import { TranslocoModule } from '@ngneat/transloco';
    import { TranslocoDecimalPipe, TranslocoLocaleModule } from '@ngneat/transloco-locale';
    
    @Injectable({ providedIn: 'root' })
    class L10nTestService {
      decimalValue: string;
    
      constructor(private translocoDecimalPipe: TranslocoDecimalPipe) {
        this.decimalValue = translocoDecimalPipe.transform(1234567890.123456);
      }
    }
    
    describe('L10ntestService', () => {
      let spectator: SpectatorService<L10nTestService>;
      const createService = createServiceFactory<L10nTestService>({
        service: L10nTestService,
        imports: [
          TranslocoModule,
          TranslocoLocaleModule.init()
        ]
      });
    
      beforeEach(() => spectator = createService());
    
      it('decimal value should be transformed', () => {
        expect(spectator.service.decimalValue).toBe('1,234,567,890.123');
      });
    });
    7 replies
    Fayas Ismail
    @simfyz
    @shaharkazaz Hi, I have a project with transloco with standard configurations. I have my i18n in the assets under folders for feature modules. Now I'm planning to move them to the feature directory using scope and inline loaders. But when I tried that translations are always loaded from assets and the loader returns 404 by looking at the files in assets not in the feature directory I assigned. Am I missing something? can you please help me.
    6 replies
    Fayas Ismail
    @simfyz
    image.png
    François
    @GrandSchtroumpf
    Hello, is there a strategy to prefetch the i18n.json files to be cache for offline purpose ? When preloading the module it seems not to load the transloco scope associated.
    Philipp Feigl
    @pfeigl
    Is there an easy way to selectTranslate multiple strings and do a single subscribe (other than doing multiple selectTranslate and combineLatest the observables?)
    1 reply
    François
    @GrandSchtroumpf
    @pfeigl not to my knowledge. If you take a look at the code of the transloco-preload-lang, they are using a forkJoin with a load. But you can create your own method with an array of string that wrap a combineLatest/forkjoin if you are doing it several time.
    @shaharkazaz When running prerender I've got this this error:
    When using the default fallback, a fallback language must be provided in the config
    I supposed it's because the angular universal is trying to fetch the data on the baseUrl defined for ssr. But for prerendering the content is not available yet. How to work around this issue ?
    1 reply
    François
    @GrandSchtroumpf
    Here is my config :
    translocoConfig({
      availableLangs: ['fr', 'en'],
      defaultLang: 'fr',
      fallbackLang: 'en',
      reRenderOnLangChange: true,
      prodMode: environment.production,
      flatten: {
        aot: environment.production
      },
    })
    bagerth
    @bagerth

    I've a problem with using inline loaders.

    If a do a manual refresh of the page (F5), I get
    Missing translation for 'cookies'

    It seems the translocoService calling occurs before the translation scope has been loaded.

    export const availableLangs = [ "en", "sv" ];
    
    export const translocoScopeLoader = (loader: any) => {
        return availableLangs.reduce((acc, lang) => {
            acc[lang] = () => loader(lang.;
            return acc;
        }, {});
    };
    
    @Component({
        selector: 'cookies',
        templateUrl: 'cookies.component.html',
        providers: [
          {
            provide: TRANSLOCO_SCOPE,
            useValue: {
              scope: 'cookies',
              loader: translocoScopeLoader((lang: string) => import(`./i18n/${lang}.json`))
            }
          }
        ]
    })
    
    export class CookiesComponent {
    
        constructor(
            private translocoService: TranslocoService) {
    
                this.translocoService
                    .selectTranslate("cookies")
                    .subscribe((value: string) => {
                            console.log(value);
                        }
                    );
            }
        }
    }
    How do I know when the scope has been successfully loaded? I don't want to make any calls to translateService until the scope has been properly fetched.
    bagerth
    @bagerth
    If found a solution at last. Sharing is caring, so here it comes :)
    export class CookiesComponent {
    
        constructor(
            @Inject(TRANSLOCO_SCOPE) private scope: ProviderScope,
            private translocoService: TranslocoService) {
    
                this.translocoService
                    .selectTranslate("cookies", {}, this.scope)
                    .subscribe((value: string) => {
                            console.log(value);
                        }
                    );
            }
        }
    }
    The scope needs to be injected to the constructor. Additional attributes was needed to the selectTranslate trigger as well.
    Perrine
    @AlaplayaW
    Hello, I'm new with transloco and I need to translate the return part with transloco in order to use my frequency pipe in my template. How can I do please?
    import { PipeTransform, Pipe } from '@angular/core'
    
    @Pipe({
        name: 'frequency'
    })
    
    export class FrequencyPipe implements PipeTransform {
    
        transform(frequency: any): string {
    
            switch (frequency) {
                case 'WEEKLY':
                    return "toutes les semaines"
                case 'MONTHLY':
                    return "tous les mois"
                case 'SEMIANNUALLY':
                    return "deux fois par an"
                case 'QUARTERLY':
                    return "chaque trimestre"
            }
    
        }
    }
    5 replies
    Fahad Mansoor
    @fahadm

    Hi guys, I was looking at this ngneat/transloco#110

    And the last comment in that issue got me thinking, What is the prefferred way of cache busting with transloco

    1 reply
    card cat
    @tomvbe:matrix.org
    [m]
    Hi guys, I just discovered transloco and could not find anything regarding localization of routes in the docs (something like https://github.com/Greentube/localize-router does for ngx-translate. Did I miss this or is this feature not (yet?) included?
    2 replies
    bagerth
    @bagerth

    Is it possible to get a translation file when working with a scope from an inline loader? @shaharkazaz

    I tried using selectTranslation(), but it doesn't get the translations specified in an inline loaded scope.

    image.png
    bagerth
    @bagerth

    I think I found a solution to my recent post.

    I added this to the constructor
    @Inject(TRANSLOCO_SCOPE) private scope: ProviderScope

    Then I changed the method trigger from:
    selectTranslation()
    to
    selectTranslation(this.scope.scope)

    It seems to do the trick!

    fnuMMS
    @fnuMMS
    Hey :) I am using transloco-keys-manager find to check my t-keys to be covered but the find-cmd also find things nothing to do with translations in my HTML stuff. So the find-cmd show errors when using the routerlink attribute for example: [routerLink]="['..', param1 ]" ... does anybody know how can I prevent this kind of findings?
    1 reply
    Lukas Heddendorp
    @heddendorp
    I have a problem with the keys manager, for some scopes it creates subdirectories. The goal was to only have one file per langauge though.
    I removed all scope providers but for some reason a couple of files lead to subdirectory scopes.
    When running the app, it prints the translation key instead of the placeholder form the file
    Lukas Heddendorp
    @heddendorp
    So the question would be how to configure the key manager in a way that it puts all keys into one file
    Shahar Kazaz
    @shaharkazaz
    @heddendorp Hey, scopes are supposed to be different files since they are used for lazy loading (besides the benefits of a more organized translation) so if you intend that your keys will be in a single file you shouldn't use them.
    If you are still having problems please provide a small reproduction so we can have a better grasp of what's going on :slight_smile:
    1 reply
    Martin Bech
    @sithwarrior

    I need to use som translations in a Modal, where I can’t use transloco in the template, so Im using the transloco service. I need to translate 4 strings, title, message, ok and cancel, normally in the old days of angular translate I would call the method with and array of strings like so [ “ALERT_HEADER”,”ALERT_MESSAGE”,”ALERT_OK”, “ALERT_CANCEL” ] and I would get back an object where I would be able to use it like this translation.ALERT_HEADER, translation.ALERT_MESSAGE etc.

    However with translocoservice.translate or translocoservice.selectTranslate I only get back and array of strings, so I have to use it as an array translation[0] for the alert header etc.

    Is there a better way of doing this?

    3 replies
    António Santos
    @antonio.santos_gitlab

    Hey transloco community,

    I know I can pass a ProviderScope to:
    this.translocoService.selectTranslate(key, {}, scope);

    But I need a way of getting all the keys from an object or single file within the scope, can I also pass a ProviderScope to:
    this.translocoService.selectTranslation() or this.translocoService.selectTranslateObject()

    AceVentura
    @AceVentura
    Hello. Anyone has a clue on why transloco doesn't work on appcomponent? Tried with instant (ngOnInit) and pipe. No dice. It works perfectly if I use in any other place
    1 reply
    bagerth
    @bagerth

    @antonio.santos_gitlab
    I had the exact same problem when I was working with a scope from an inline loader.

    I solved it by using
    @Inject(TRANSLOCO_SCOPE) private scope: ProviderScope
    followed by
    selectTranslation(this.scope.scope)

    More information (and a code example) some posts above.

    António Santos
    @antonio.santos_gitlab

    @antonio.santos_gitlab
    I had the exact same problem when I was working with a scope from an inline loader.

    I solved it by using
    @Inject(TRANSLOCO_SCOPE) private scope: ProviderScope
    followed by
    selectTranslation(this.scope.scope)

    More information (and a code example) some posts above.

    I saw your posts above, that's what helped me most to achieve a component scope for my project :)
    But that selectTranslation part didn't work for me, and I don't know why.

    1 reply
    Jean-Philippe
    @PooSham
    Hi! We use calls to selectTranslateObject() in our code, and we realized it doesn't give us the fallback translation when a key is missing in a language (we have set fallbackLang to true in the config). selectTranslate() works. is this a known issue? Is there a reason for this?
    2 replies
    Robin
    @openscript
    Hello :) I've a module with providers: [{ provide: TRANSLOCO_SCOPE, useValue: 'login' }],. In the component templates and the components I'm using transloco successfully, but the transloco-key-manager complains for the translations which are done by the service inside the component.
    this.snackBar.open(this.i18n.translate('login.unknownCredentials'), undefined, { duration: 3000 });
    Now when I run yarn run transloco-keys-manager find --translations-path assets/i18n I get missing keys for login.unknownCredentials
    image.png
    Brian
    @seadonk
    When using the default locale mappings, I noticed that translocoLocaleService.localeChanges$ is updated twice with the new value instead of once. It's lower priority, but if it is not just me, I can open an issue.
    Thierry Lévèque
    @tleveque23
    Hi, I just tried creating a brand new Angular project following the Getting Started guide.... And it does not work.... I am using node v12 and Angular 11 (but same problem with Angular 10). There is no error, but the ressource files are never loaded. Here is a stackblitz example I just did: https://stackblitz.com/github/tleveque23/translocotest. Any idea what I am doing wrong?
    RoboZoom
    @RoboZoom
    Greetings all - I'm having an issue where unit tests fail when including the *transloco structural directive in my template. Via manual usage (ie me running the software, and clicking) everything works great. But in executing the unit test, my debugElement.query operations are not finding the divs with transloco included. Refactored to exclude the directive, there are no problems
    Here is the template code:
    <div *transloco="let t;">
      <div nz-popconfirm
           [nzPopconfirmTitle]="text"
           [nzOkText]="text"
           [nzCancelText]="text"
           (nzOnConfirm)="deleteRow()">
        <fa-icon class="trashIcon" [icon]="trash"></fa-icon>
      </div>
    </div>
    When refactored to this, it passes:
    <div>
      <div nz-popconfirm
           [nzPopconfirmTitle]="text"
           [nzOkText]="text"
           [nzCancelText]="text"
           (nzOnConfirm)="deleteRow()">
        <fa-icon class="trashIcon" [icon]="trash"></fa-icon>
      </div>
    </div>
    Here's the unit test:
    it('emits own id on confirmed click', () => {
        const testID = '12a';
        component.id = testID;
        popDebugEl = fixture.debugElement.query(By.css('div[nz-popconfirm]'));
    
        let emittedID: string | number;
        component.deleteItem.subscribe((id) => (emittedID = id));
    
        console.log(popDebugEl);
        popDebugEl.triggerEventHandler('nzOnConfirm', null);
    
        expect(emittedID).toEqual(testID);
      });