Skip to content

Commit 59710b2

Browse files
committed
fix: track loader instead of using a pending flag
1 parent 0edde02 commit 59710b2

File tree

1 file changed

+34
-26
lines changed

1 file changed

+34
-26
lines changed

projects/ngx-translate/src/lib/translate.service.ts

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { inject, Injectable, InjectionToken } from "@angular/core";
2-
import { concat, defer, forkJoin, isObservable, Observable, of } from "rxjs";
2+
import { concat, defer, finalize, forkJoin, isObservable, Observable, of, tap } from "rxjs";
33
import { concatMap, map, shareReplay, switchMap, take } from "rxjs/operators";
44
import { MissingTranslationHandler } from "./missing-translation-handler";
55
import { TranslateCompiler } from "./translate.compiler";
@@ -58,9 +58,7 @@ const makeObservable = <T>(value: T | Observable<T>): Observable<T> => {
5858

5959
@Injectable()
6060
export class TranslateService implements ITranslateService {
61-
protected loadingTranslations!: Observable<InterpolatableTranslationObject>;
62-
protected pending = false;
63-
protected _translationRequests: Record<Language, Observable<TranslationObject>> = {};
61+
protected loadingTranslations: Record<Language, Observable<InterpolatableTranslationObject>> = {};
6462
protected lastUseLanguage: Language | null = null;
6563

6664
protected currentLoader = inject(TranslateLoader);
@@ -151,6 +149,11 @@ export class TranslateService implements ITranslateService {
151149
return of(this.store.getTranslations(lang));
152150
}
153151

152+
protected isLoading(): boolean
153+
{
154+
return Object.keys(this.loadingTranslations).length > 0;
155+
}
156+
154157
/**
155158
* Changes the lang currently used
156159
*/
@@ -185,12 +188,10 @@ export class TranslateService implements ITranslateService {
185188
/**
186189
* Retrieves the given translations
187190
*/
188-
protected loadOrExtendLanguage(lang: Language): Observable<TranslationObject> | undefined {
191+
protected loadOrExtendLanguage(lang: Language): Observable<InterpolatableTranslationObject> | undefined {
189192
// if this language is unavailable or extend is true, ask for it
190193
if (!this.store.hasTranslationFor(lang) || this.extend) {
191-
this._translationRequests[lang] =
192-
this._translationRequests[lang] || this.loadAndCompileTranslations(lang);
193-
return this._translationRequests[lang];
194+
return this.loadAndCompileTranslations(lang);
194195
}
195196

196197
return undefined;
@@ -216,30 +217,36 @@ export class TranslateService implements ITranslateService {
216217
protected loadAndCompileTranslations(
217218
lang: Language,
218219
): Observable<InterpolatableTranslationObject> {
219-
this.pending = true;
220220

221-
const loadingTranslations = this.currentLoader
222-
.getTranslation(lang)
223-
.pipe(shareReplay(1), take(1));
221+
if(this.loadingTranslations[lang]) {
222+
return this.loadingTranslations[lang];
223+
}
224224

225-
this.loadingTranslations = loadingTranslations.pipe(
226-
map((res: TranslationObject) => this.compiler.compileTranslations(res, lang)),
227-
shareReplay(1),
228-
take(1),
225+
const translations$ = this.currentLoader.getTranslation(lang).pipe(
226+
map((res: TranslationObject) =>
227+
this.compiler.compileTranslations(res, lang),
228+
),
229+
tap((compiled: InterpolatableTranslationObject) => {
230+
this.store.setTranslations(lang, compiled, this.extend);
231+
}),
232+
finalize(() => {
233+
delete this.loadingTranslations[lang];
234+
}),
235+
// cache the single result & share it across all subscribers
236+
shareReplay({ bufferSize: 1, refCount: true }),
229237
);
230238

231-
this.loadingTranslations.subscribe({
232-
next: (res: InterpolatableTranslationObject) => {
233-
this.store.setTranslations(lang, res, this.extend);
234-
this.pending = false;
235-
},
239+
this.loadingTranslations[lang] = translations$;
240+
241+
// trigger loading if nobody subscribes from outside
242+
translations$.subscribe({
236243
error: (err) => {
237244
void err;
238-
this.pending = false;
245+
// console.error(err);
239246
},
240247
});
241248

242-
return loadingTranslations;
249+
return translations$;
243250
}
244251

245252
/**
@@ -390,9 +397,10 @@ export class TranslateService implements ITranslateService {
390397
if (!isDefinedAndNotNull(key) || !key.length) {
391398
return of("");
392399
}
400+
393401
// check if we are loading a new translation to use
394-
if (this.pending) {
395-
return this.loadingTranslations.pipe(
402+
if (this.lastUseLanguage && this.loadingTranslations[this.lastUseLanguage]) {
403+
return this.loadingTranslations[this.store.getCurrentLang()].pipe(
396404
concatMap(() => {
397405
return makeObservable(this.getParsedResult(key, interpolateParams));
398406
}),
@@ -514,7 +522,7 @@ export class TranslateService implements ITranslateService {
514522
* Deletes inner translation
515523
*/
516524
public resetLang(lang: Language): void {
517-
delete this._translationRequests[lang];
525+
delete this.loadingTranslations[lang];
518526
this.store.deleteTranslations(lang);
519527
}
520528

0 commit comments

Comments
 (0)