Comments (15)
@david-bulte Hi, what is your versions?
angular
i18next
angular-18next
from angular-i18next.
Here is demo app runninig on latest version
https://github.com/Romanchuk/angular-i18next-demo
https://romanchuk.github.io/angular-i18next-demo/
from angular-i18next.
My versions:
- "i18next": "^15.0.4",
- "i18next-browser-languagedetector": "^3.0.1",
- "i18next-xhr-backend": "^2.0.1",
- "@angular/core": "^7.2.7",
- "angular-i18next": "^6.0.0"
Here's how I use it. As you see I'm listening to the events in the constructor of a pipe. The console.log('>>>>>> translation', translation); is not carried out. Directly using i18next (_i18next in the code below) does work.
import { ChangeDetectorRef, OnDestroy, OnInit, Pipe, PipeTransform } from '@angular/core';
import { I18NextPipe, I18NextService } from 'angular-i18next';
import * as i18n from 'i18next';
const _i18next = i18n.default;
@Pipe({
name: 'nexuzhealthI18n',
pure: false
})
export class I18nPipe implements PipeTransform, OnDestroy {
private langChanged = this.languageChanged.bind(this);
constructor(private i18Next: I18NextService, private i18NextPipe: I18NextPipe, private changeDetector: ChangeDetectorRef) {
// bug? cf. https://github.com/Romanchuk/angular-i18next/issues/27
this.i18Next.events.languageChanged.subscribe(translation => {
console.log('>>>>>> translation', translation);
this.changeDetector.markForCheck();
})
_i18next.on('languageChanged', this.langChanged);
}
transform(value: any, args?: any): any {
return this.i18NextPipe.transform(value, args);
}
ngOnDestroy(): void {
_i18next.off('languageChanged', this.langChanged)
}
languageChanged(lng) {
this.changeDetector.markForCheck();
}
}
from angular-i18next.
I have reproduced it on demo app, it is not a bug. You are injecting "i18Next: I18NextService", but you should inject it throught token like this:
@Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService
I guess the reason is that you have inited i18next module using token (as recommended)
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE],
multi: true
}
but then you should inject I18NEXT_SERVICE token everywhere in your app, because you inited it.
You injecting I18NextService, but it was not inited (events was not subscribed).
May be i should depricate I18NextService provider to remove this confusion
from angular-i18next.
This is working much better, thanks! Still I have a little problem. The languageChanged event is not being called in a module that was lazy loaded. I noticed that the ITranslationService instance (now injected via @Inject(I18NEXT_SERVICE)) is not the same in the root as in the (lazy loaded) module, maybe that is the reason?
Here's a snippet of my configuration:
@NgModule({
imports: [CommonModule, I18NextModule.forRoot()],
declarations: [I18nPipe],
exports: [I18NextModule, I18nPipe] // re-exporting I18NextModule, I18nPipe is my own
})
export class SharedUtilI18nModule {
static forRoot(config: I18NextConfig = {}): ModuleWithProviders {
return {
ngModule: SharedUtilI18nModule,
providers: [
{provide: i18next_config, useValue: config},
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE, i18next_config],
multi: true
}
]
}
}
}
In my (root) AppModule, I import this like so:
SharedUtilI18nModule.forRoot({ns: {ns: ['gp', 'auth', 'common'], merge: true}})
While in the lazy-loaded module, I just import SharedUtilI18nModule (to be able to use the i18next pipe, SharedUtilI18nModule is re-exporting I18NextModule):
@NgModule({
imports: [
//... here are some more modules
SharedUtilI18nModule
],
declarations: [InboxPageComponent]
})
export class MoaprGpFeatureInboxModule {}
What am I doing wrong? Is it normal that the ITranslationService isn't a singleton?
from angular-i18next.
ITranslationService is a singleton, but in your lazy module there is the other Injector, that has no instances of ITranslationService and it creates it own (the new one).
I have in my projects lazy modules and i do it like this:
- AppModule: import I18NextModule.forRoot(..)
- Lazy module: import I18NextModule to provide pipes. ITranslationService would be refenced to root ITranslationService and it will be single for whole app.
In your case you should divide your SharedUtilI18nModule and I18NextModule.forRoot, init I18NextModule in AppModule.
SharedUtilI18nModule is only for your pipes and it still imports I18NextModule (without forRoot). And it don't need to export I18NextModule.
InboxPageComponent imports both I18NextModule and SharedUtilI18nModule
The main thing i don't understand: Why do you do it? Why don't you use already implemented mecanisms?
from angular-i18next.
I will try it out later. As for your question, I was looking for a way to dynamically change the translations: you change the language and all translations are immediately refreshed, also the ones in components with ChangeDetection.OnPush (comparable to the AsyncPipe). But maybe you know another way ? :)
from angular-i18next.
Here are the reasons why i left idea on making pipes dynamic/impure:
#11 (comment)
In early versions i tryied to implement impure pipes, but left this idea for several reasons:
- Some custom controls or pipes can be dependent on angular LOCALE_ID token. So we want to change angular LOCALE_ID with i18next language.
{
provide: LOCALE_ID,
deps: [I18NextService],
useFactory: (i18next: I18NextService) => {
return i18next.language; //string: 'en', 'ru'...
}
}
The problem is that angular IOC container resolves dependencies as singleton, once LOCALE_ID was requested it will always resolve as the same value (first resolved). The only way to get actual LOCALE_ID value is to register LOCALE_ID as factory function, but than it will break libraries that expect LOCALE_ID to be 'string' (not function).
Here is my stackoverflow question: Dynamicly get LOCALE_ID (resolve per request)
-
Custom components with own localization support mostly require complete reinit on language change.
-
Also most l10n, i18n and date format (momentjs) angular pipes are pure, and changing i18next language or LOCALE_ID won't trigger pipe change detection for them.
-
Possible memory leaks and perfomant issues. For example zonejs automatically trigger change detection as a result of async operations, this means using jquery libs with ajax could cause your page (full of impure pipes) freeze.
That is why i ended up with simply refreshing page with a new language. We only need to setup right language, locale and formats on angular initialization.
Also i had impure i18next pipe implementation that was statefull - it had memoisation that returned already translated result if input params and language did not change. It worked well. But in my real world projects language changed immediately, but "angular moment " pipes was not called (they are pure), third party controls also needed to be manually reinit...
This experience i had more than one year ago (with angular v2), maybe today it's more possible) i would like to see implementation that would resolve problems that i mentioned above
from angular-i18next.
Hello, I'm an apprentice developer. I would like to have several values that I return from my database for the same Angular interpolation variable.
What is i18next capable of solving this problem?
Here is my configuration in app module :
export function appInit(i18next: ITranslationService) {
return () => i18next
.use(detector)
.use(backend)
.use(sprintf)
.init({
whitelist: ['en', 'fr'],
fallbackLng: 'en',
debug: true,
returnEmptyString: false,
returnObjects: true,
ns: [
'translation'
],
backend: {
loadPath: "./assets/i18n/{{lng}}/{{ns}}.json"
},
lng: 'fr',
// overloadTranslationOptionHandler: sprintf.overloadTranslationOptionHandler,
});
}
export function localeIdFactory(i18next: ITranslationService) {
return i18next.language;
}
export const I18N_PROVIDERS = [
{
provide: APP_INITIALIZER,
useFactory: appInit,
deps: [I18NEXT_SERVICE],
multi: true
},
{
provide: LOCALE_ID,
deps: [I18NEXT_SERVICE],
useFactory: localeIdFactory
}];
this is my JSON "translation.json":
"models": {
"contacts": {
"attributes": {
"roles": {
"author": "Auteur",
"custodian": "Administrateur",
"distributor": "Distributeur",
"originator": "Créateur",
"owner": "Propriétaire",
"pointOfContact": "Point de contact",
"principalInvestigator": "Analyste principal",
"processor": "Responsable du traitement",
"publisher": "Éditeur (publication)",
"resourceProvider": "Fournisseur",
"user": "Utilisateur"
}
}
},
here is my HTML:
{{ author_or_user.contact.name }}
{{ author_or_user.contact.addressLine1OrNull }}
{{ author_or_user.contact.cityOrNull }}, {{ author_or_user.contact.zipCodeOrNull }}
{{ author_or_user.country }}
{{ author_or_user.contact.phoneNumberOrNull }}
{{ author_or_user.contact.emailOrNull }}
from angular-i18next.
@DevDemba Hello, i'm not sure i understand what are you trying to do and what is your problem.
from angular-i18next.
Romanchuk Hello, look at my screenshot.
In my contact block, I want to display a different role for each iteration (for each block displayed on the front) based on the filter values of my API.
I managed to translate the standard variables but not the variables where the values are random.
I would like to put interpolation variables in my json eventually in order to select a translation to apply according to the filtered role.
thanks
from angular-i18next.
@DevDemba Did you tried to concat key and translate it?
{{ ('models.contacts.attributes.roles.' + roleVariable) | i18next }}
from angular-i18next.
@Romanchuk Yes exactly. 👍 It worked.
Thank you very much for your help.
I double-checked and I had badly concatenated.
I persist in trying to put the doubles {{ }}.
from angular-i18next.
You are welcome.
Closing issue
from angular-i18next.
sorry I have posted quetion on wrong github repo I think my question is related to this conversation here it is can anyone please help I am trying for 4 days now . i18next/ng-i18next#149
from angular-i18next.
Related Issues (20)
- Is it possible to publish the 15.0 pre-release version to npm? HOT 2
- Interpolation is not working anymore HOT 4
- Property 'initialized' in type 'I18NextEvents' is not assignable to the same property in base type 'ITranslationEvents'. HOT 4
- Is it possible to use this library with Angular Universal and SSR? HOT 4
- New typings prevents passing interpolation to `ITranslationService` HOT 1
- Interpolation Format issues with numbers / dates or i18nextCap HOT 2
- Integration to Angular 16 HOT 9
- angular version issue HOT 1
- Check if there is a translation for the specified key HOT 1
- Update to last i18next version HOT 3
- Mock angular-i18next in Jest HOT 2
- Error when building project in docker HOT 3
- Nesting example HOT 1
- Consider providing a `ng add` schematics HOT 1
- i18next::translator: missingKey on simple implementation HOT 1
- Unit test run error HOT 3
- Change Language without reloading page HOT 2
- Build error when updating to 14.2.0 with strict typing HOT 24
- Getting started with Angular v15 HOT 4
- Support i18next v22 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from angular-i18next.