angularangular-pipetransloco

TranslocoCurrencyPipe NullInjectorError


I am currently trying to upgrade the Transloco version in our project. Previously we were on Transloco 4.3.0 and Transloco-MessageFormat 4.1.0. The goal ist to upgrade them to the newest version (7).

As stated in the breaking changed for v5, I changes the way of providing, as the new way should be. See TranslocoRootModule:

@NgModule({
    imports: [],
    exports: [TranslocoModule],
    providers: [
        provideTransloco(
            {
                config: {
                    availableLangs: ['de', 'en'],
                    defaultLang: 'de',
                    missingHandler: {
                        allowEmpty: true,
                    },
                    reRenderOnLangChange: true,
                    prodMode: false,
                },
                loader: TranslocoHttpLoader
            }
        ),
        provideTranslocoMissingHandler(TranslocoCustomMissingHandler),
        provideTranslocoMessageformat({locales: ['de-DE']}),
        provideTranslocoLocale({defaultLocale: 'de-DE'}),
    ],
})
export class TranslocoRootModule { ... }

As it stands, the TranslocoCurrenyPipe is working perfectly fine with in-template use. But in some occasions we also need to use the pipe within the ts file of a component or a service. Which worked perfectly fine before upgrading. See:

constructor(
    private readonly currencyPipe: TranslocoCurrencyPipe
) { ... }

const priceStr = `${this.currencyPipe.transform(
    price,
    'symbol',
    { minimumFractionDigits: 0, maximumFractionDigits: 0 },
    data.price.total.currency,
)}`;

This implementation now leads to an Error being thrown in the Browser (Regarding the new standalone way?). See:

ERROR NullInjectorError: R3InjectorError(AppModule)[GoogleMapsService -> TranslocoCurrencyPipe -> ChangeDetectorRef -> ChangeDetectorRef]: 
  NullInjectorError: No provider for ChangeDetectorRef!
    at NullInjector.get (core.mjs:1662:27)
    at R3Injector.get (core.mjs:3108:33)
    at R3Injector.get (core.mjs:3108:33)
    at injectInjectorOnly (core.mjs:1106:40)
    at ɵɵinject (core.mjs:1112:60)
    at inject (core.mjs:1198:12)
    at <instance_members_initializer> (jsverse-transloco-locale.mjs:878:17)
    at new BaseLocalePipe (jsverse-transloco-locale.mjs:876:1)
    at new TranslocoCurrencyPipe (jsverse-transloco-locale.mjs:897:1)
    at BaseLocalePipe_Factory (jsverse-transloco-locale.mjs:890:16)

I know this is pretty few. I sadly can't get it done to build you guys sample project, since I am not able to set it up the same way, that it leads to the same error. I tried to, but failed along that way sadly. Also it is not possible to share the whole project with you, due to some restrictions.

So this is more like a hail mary, hoping that you guys maybe see the issue from these informations as an act of desperation. Maybe you can help. I can provide further information if needed.


Solution

  • Under the hood the currency pipe uses the TranslocoLocaleService. In TypeScript code, it is better practice to directly use the service instead of injecting the pipe. You can check out the API of the service in the docs. Updated code:

    export class MyComponent {
      constructor(private readonly localeService: TranslocoLocaleService) {}
    
      getPrice(price: number, currency: string) {
        const priceStr = `${this.localeService.localizeNumber(
          price,
          'currency',
          undefined,
          {
            currency,
            minimumFractionDigits: 0,
            maximumFractionDigits: 0,
          },
        )}`;
      }
    }
    

    As you can see, this requires a bit of refactoring.