core
core copied to clipboard
Subsequent calls to translateService.use(language) may change to an older language
I'm submitting a ... (check one with "x")
[X] bug report => check the FAQ and search github for a similar issue or PR before submitting
[ ] support request => check the FAQ and search github for a similar issue before submitting
[ ] feature request
Current behavior
Let's suppose you call translateService.use("de")
and then translateService.use("en")
. Now, if de.json takes 500ms to load and en.json takes 100ms to load, in the end the current language will be "de".
Expected/desired behavior
The current language should be the one of the last .use()
call, in the example above en
.
Reproduction of the problem If the current behavior is a bug or you can illustrate your feature request better with an example, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar. You can use this template as a starting point: http://plnkr.co/edit/tpl:XXwyUYS6ZL7qVD9I2l0g
What is the expected behavior?
What is the motivation / use case for changing the behavior?
Please tell us about your environment:
-
ngx-translate version: x.x.x 9.0.1
-
Angular version: 2.x.x 5.0.0
-
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ] Chrome
If needed I can provide a PR with the fix.
It looks similar to #224. @beradrian what would be your fix here?
You have this method in TranslateService
public use(lang: string): Observable<any> {
// don't change the language if the language given is already selected
if (lang === this.currentLang) {
return of(this.translations[lang]);
}
let pending: Observable<any> = this.retrieveTranslations(lang);
if (typeof pending !== "undefined") {
// on init set the currentLang immediately
if (!this.currentLang) {
this.currentLang = lang;
}
pending.pipe(take(1))
.subscribe((res: any) => {
this.changeLang(lang);
});
return pending;
} else { // we have this language, return an Observable
this.changeLang(lang);
return of(this.translations[lang]);
}
}
I would modify it to
private currentLangSubscription: Subscription;
public use(lang: string): Observable<any> {
// don't change the language if the language given is already selected
if (lang === this.currentLang) {
return of(this.translations[lang]);
}
let pending: Observable<any> = this.retrieveTranslations(lang);
if (typeof pending !== "undefined") {
// on init set the currentLang immediately
if (!this.currentLang) {
this.currentLang = lang;
}
if (this.currentLangSubscription) {
this.currentLangSubscription.unsubscribe();
}
this.currentLangSubscription = pending.pipe(take(1))
.subscribe((res: any) => {
delete this.currentLangSubscription;
this.changeLang(lang);
});
return pending;
} else { // we have this language, return an Observable
this.changeLang(lang);
return of(this.translations[lang]);
}
}
Similarly you can do the same for default language.
Looking good, thanks for sharing! Maybe it would ease integration if PR was submitted? Would you like to submit it or should I?
@ocombe any thoughts?
Yes, sure I can submit a PR if you want. Just let me know. Thanks!
Is it scheduled to fix this bug in a future version?
Hi,
is there any update or workaround for this?
Thank you!