Skip to content

Commit f3a723c

Browse files
authored
Merge pull request #1596 from ngx-translate/1585-fixprovidechildtranslateservice-not-calling-the-loader-when-the-lazy-loaded-module-is-first-loaded
feat(store): loaders
2 parents 3227984 + 5df7dda commit f3a723c

File tree

2 files changed

+63
-8
lines changed

2 files changed

+63
-8
lines changed

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

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import { inject, Injectable, InjectionToken } from "@angular/core";
1+
import { inject, Injectable, InjectionToken, OnDestroy } from "@angular/core";
22
import { concat, defer, forkJoin, isObservable, Observable, of } 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";
66
import { TranslateLoader } from "./translate.loader";
77
import { InterpolateFunction, TranslateParser } from "./translate.parser";
88
import { TranslateStore } from "./translate.store";
9-
import { insertValue, isArray, isDefinedAndNotNull, isDict, isString } from "./util";
9+
import { insertValue, isArray, isDefinedAndNotNull, isDict, isString, mergeDeep } from "./util";
1010

1111
/**
1212
* Configuration object for the translation service.
@@ -173,7 +173,7 @@ export abstract class ITranslateService {
173173
}
174174

175175
@Injectable()
176-
export class TranslateService implements ITranslateService {
176+
export class TranslateService implements ITranslateService, OnDestroy {
177177
private loadingTranslations!: Observable<InterpolatableTranslationObject>;
178178
private pending = false;
179179
private _translationRequests: Record<Language, Observable<TranslationObject>> = {};
@@ -245,6 +245,12 @@ export class TranslateService implements ITranslateService {
245245
if (config.extend) {
246246
this.extend = true;
247247
}
248+
249+
this.store.addLoader(this.currentLoader);
250+
}
251+
252+
ngOnDestroy(): void {
253+
this.store.removeLoader(this.currentLoader);
248254
}
249255

250256
/**
@@ -341,11 +347,25 @@ export class TranslateService implements ITranslateService {
341347
): Observable<InterpolatableTranslationObject> {
342348
this.pending = true;
343349

344-
const loadingTranslations = this.currentLoader
345-
.getTranslation(lang)
346-
.pipe(shareReplay(1), take(1));
350+
const loaders = this.store.getLoaders();
351+
let loadAndMerge: Observable<TranslationObject>;
352+
353+
if (loaders.length === 0) {
354+
return of({} as InterpolatableTranslationObject);
355+
} else if (loaders.length === 1) {
356+
loadAndMerge = loaders[0].getTranslation(lang);
357+
} else {
358+
const requests: Observable<TranslationObject>[] = loaders.map((loader) =>
359+
loader.getTranslation(lang).pipe(take(1)),
360+
);
361+
loadAndMerge = forkJoin(requests).pipe(
362+
map((results: TranslationObject[]) =>
363+
results.reduce((acc, curr) => mergeDeep(acc, curr), {} as TranslationObject),
364+
),
365+
);
366+
}
347367

348-
this.loadingTranslations = loadingTranslations.pipe(
368+
this.loadingTranslations = loadAndMerge.pipe(shareReplay(1), take(1)).pipe(
349369
map((res: TranslationObject) => this.compiler.compileTranslations(res, lang)),
350370
shareReplay(1),
351371
take(1),
@@ -362,7 +382,7 @@ export class TranslateService implements ITranslateService {
362382
},
363383
});
364384

365-
return loadingTranslations;
385+
return this.loadingTranslations;
366386
}
367387

368388
/**

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ import {
99
TranslationChangeEvent,
1010
} from "./translate.service";
1111
import { getValue, mergeDeep } from "./util";
12+
import { TranslateLoader } from "./translate.loader";
1213

1314
export type DeepReadonly<T> = {
1415
readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
1516
};
1617

18+
interface LoaderReference {
19+
loader: TranslateLoader;
20+
count: number;
21+
}
22+
1723
@Injectable()
1824
export class TranslateStore {
1925
private _onTranslationChange: Subject<TranslationChangeEvent> =
@@ -28,6 +34,35 @@ export class TranslateStore {
2834
private translations: Record<Language, InterpolatableTranslationObject> = {};
2935
private languages: Language[] = [];
3036

37+
private loaders: LoaderReference[] = [];
38+
39+
public addLoader(loader: TranslateLoader): void {
40+
const existingLoader = this.getLoaderRef(loader);
41+
if (existingLoader) {
42+
existingLoader.count++;
43+
} else {
44+
this.loaders.push({ loader, count: 1 });
45+
}
46+
}
47+
48+
public removeLoader(loader: TranslateLoader): void {
49+
const existingLoader = this.getLoaderRef(loader);
50+
if (existingLoader) {
51+
existingLoader.count--;
52+
if (existingLoader.count === 0) {
53+
this.loaders = this.loaders.filter((ref) => ref.loader !== loader);
54+
}
55+
}
56+
}
57+
58+
private getLoaderRef(loader: TranslateLoader): LoaderReference | undefined {
59+
return this.loaders.find((ref) => ref.loader === loader);
60+
}
61+
62+
public getLoaders(): TranslateLoader[] {
63+
return this.loaders.map((ref) => ref.loader);
64+
}
65+
3166
public getTranslations(language: Language): DeepReadonly<InterpolatableTranslationObject> {
3267
return this.translations[language];
3368
}

0 commit comments

Comments
 (0)