[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[x] Support request
[ ] Other... Please describe:
I just switched from ngx-translate to transloco in order to deal with lazy loading issues with my libraries.
So I'm using the Inline Loaders feature.
My issue is not related to transloco itself, but how to use transloco when building a library with ng-packagr.
Here is the transloco Inline Loader example from the doc :
export const loader = ['en', 'es'].reduce((acc, lang) => {
acc[lang] = () => import(`../i18n/${lang}.json`);
return acc;
}, {});
It uses dynamic import. But ng-packagr does not support it for now. See this this issue.
My question is how to deal with this ? I believe Ng-packagr is used a lot and I wonder how you guys handle this situation. Inline Loaders seems to be meant to work with library, so I suppose this need is common.
Thank you
Angular version: 8.2.11
Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [x] Firefox version 70
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
For Tooling issues:
- Node version: 10.16.0
- Platform: Windows
Others:
ng-packagr: 5.7.0
@SparkMonkey Hi,
As you mentioned, it's not a Transloco issue. It's an issue with ng-packager that we hope they will resolve in the future.
The inline loaders were introduced to allow translations encapsulation of lazy load modules.
What I can suggest in your case is to use setTranslation and load them eagerly if someone uses the library:
```ts
import en from '....';
import es from '....';
export class YourModule {
constructor(private translocoService: TranslocoService) {
translocoService.setTranslation(en, 'en');
translocoService.setTranslation(es, 'es');
}
}
Thank you for your fast answer.
I'm trying it but I'm struggling with the json import, with the message "Unexpected token / in JSON at position 0."
I'll keep you informed
Ok I have found why I couldn't build since I added the eager import.
The i18n json file embedded in dist, thanks to the import, is sadly prefixed by the following :
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,use lessCode} checked by tsc
*/
This is not a valid JSON file since comments are not allowed in JSON. I'm searching how to avoid this behaviour right now.
Meanwhile I'm wondering something about your proposed solution :
Will I be able to define an i18n file for each module in the library ?
Since the scope seems to be not involved in the solution, I'm guessing that I will have to merge all my i18n files into a single one. Is that right ?
Thank you
I assume that the translation files are locally in the npm package. When you do this in your exposed module from the library:
import en from './en.json';
import es from './es.json';
export class YourNpmPackageModule {
constructor(private translocoService: TranslocoService) {
translocoService.setTranslation(en, 'en');
translocoService.setTranslation(es, 'es');
}
}
See how we use the setTranslation method. It will include both the en and the es translations (eagerly) in the library bundle. Now, when someone consumes the library, it can use its translations.
The second approach you mentioned can work too. You can copy the library translation files into your assets folder, put them under a scope name, and in your library root component providers set the scope.
@SparkMonkey Can you create a reproduction repo? I think this will advance us better towards a solution
I have tested your solution and it works !
I did the eager imports in each modules of my library (that is packaged as npm), and called setTranslation in their constructors as you proposed.
Each modules's components of my library are effectively translated according to their own i18n file, without any work in my main application that use these components.
I'm admitting that I do not understand how this works, because I expected setTranslation calls to override each others. I'm guessing there is a TranslationService instance for each module, so there is no override.
In order to help people who reads this issue, here some steps I have been through :
*transloco="let t;" in the top tag of my templates and used t('i18n.key') to do translationsThanks a lot for your support 馃憤
I don't know if it's in transloco scope, but i think these steps might help other people.
Thanks for your detailed summary. Transloco doesn't create new instance for each module. When you call setTranslation by default it merges the translations. We hope that ng-packagr will add the import support in the future, and when it does it will work out of the box. I'm closing this issue for now.
Most helpful comment
I have tested your solution and it works !
I did the eager imports in each modules of my library (that is packaged as npm), and called setTranslation in their constructors as you proposed.
Each modules's components of my library are effectively translated according to their own i18n file, without any work in my main application that use these components.
I'm admitting that I do not understand how this works, because I expected setTranslation calls to override each others. I'm guessing there is a TranslationService instance for each module, so there is no override.
In order to help people who reads this issue, here some steps I have been through :
*transloco="let t;"in the top tag of my templates and used t('i18n.key') to do translationsThanks a lot for your support 馃憤
I don't know if it's in transloco scope, but i think these steps might help other people.