Skip to content

Commit bdb43b7

Browse files
committed
refactor: improved TranslateHttpLoader config
1 parent c43c7dd commit bdb43b7

File tree

4 files changed

+84
-85
lines changed

4 files changed

+84
-85
lines changed

projects/http-loader/src/lib/http-loader-backend.spec.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from "@a
22
import { HttpTestingController, provideHttpClientTesting } from "@angular/common/http/testing";
33
import { TestBed } from "@angular/core/testing";
44
import { provideTranslateService, TranslateService, Translation } from "@ngx-translate/core";
5-
import { provideTranslateHttpLoaderFromHttpBackend, TranslateHttpLoader } from "../public-api";
5+
import { provideTranslateHttpLoader, TranslateHttpLoader } from "../public-api";
66
import { MarkerInterceptor } from "../test-helper/marker-interceptor";
77

8-
describe("TranslateLoader (HttpBackend)", () => {
8+
describe("TranslateHttpLoader (HttpBackend)", () => {
99
let translate: TranslateService;
1010
let http: HttpTestingController;
1111

@@ -20,9 +20,10 @@ describe("TranslateLoader (HttpBackend)", () => {
2020
},
2121
provideHttpClient(withInterceptorsFromDi()),
2222
provideHttpClientTesting(),
23-
TranslateService,
2423
provideTranslateService(),
25-
provideTranslateHttpLoaderFromHttpBackend(),
24+
provideTranslateHttpLoader({
25+
useHttpBackend: true,
26+
}),
2627
],
2728
});
2829

projects/http-loader/src/lib/http-loader.spec.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@ import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from "@a
22
import { HttpTestingController, provideHttpClientTesting } from "@angular/common/http/testing";
33
import { TestBed } from "@angular/core/testing";
44
import { provideTranslateService, TranslateService, Translation } from "@ngx-translate/core";
5-
import { provideTranslateHttpLoader, TranslateHttpLoader } from "../public-api";
5+
import {
6+
provideTranslateHttpLoader,
7+
TranslateHttpLoader,
8+
TranslateHttpLoaderConfig,
9+
} from "../public-api";
610
import { MarkerInterceptor } from "../test-helper/marker-interceptor";
711

8-
describe("TranslateLoader (HttpClient)", () => {
12+
describe("TranslateHttpLoader (HttpClient)", () => {
913
let translate: TranslateService;
1014
let http: HttpTestingController;
1115

12-
beforeEach(() => {
16+
const prepare = (config: Partial<TranslateHttpLoaderConfig> = {}) => {
1317
TestBed.configureTestingModule({
1418
providers: [
1519
MarkerInterceptor,
@@ -20,27 +24,54 @@ describe("TranslateLoader (HttpClient)", () => {
2024
},
2125
provideHttpClient(withInterceptorsFromDi()),
2226
provideHttpClientTesting(),
23-
TranslateService,
24-
provideTranslateHttpLoader(),
2527
provideTranslateService(),
28+
provideTranslateHttpLoader(config),
2629
],
2730
});
2831

2932
translate = TestBed.inject(TranslateService);
3033
http = TestBed.inject(HttpTestingController);
31-
});
34+
};
3235

3336
afterEach(() => {
3437
http.verify();
3538
});
3639

3740
it("should be able to provide TranslateHttpLoader", () => {
41+
prepare();
3842
expect(TranslateHttpLoader).toBeDefined();
3943
expect(translate.currentLoader).toBeDefined();
4044
expect(translate.currentLoader instanceof TranslateHttpLoader).toBeTruthy();
4145
});
4246

47+
describe("Config", () => {
48+
it("uses prefix", () => {
49+
prepare({ prefix: "XXXX/" });
50+
translate.use("en");
51+
http.expectOne("XXXX/en.json").flush({});
52+
expect(true).toBeTruthy(); // http.expectOne() is not detected by jasmine...
53+
});
54+
55+
it("uses suffix", () => {
56+
prepare({ suffix: ".XXXX" });
57+
translate.use("en");
58+
http.expectOne("/assets/i18n/en.XXXX").flush({});
59+
expect(true).toBeTruthy(); // http.expectOne() is not detected by jasmine...
60+
});
61+
62+
it("uses cache buster", () => {
63+
prepare({ enforceLoading: true });
64+
translate.use("en");
65+
http.expectOne((req) =>
66+
req.url.startsWith("/assets/i18n/en.json?enforceLoading="),
67+
).flush({});
68+
expect(true).toBeTruthy(); // http.expectOne() is not detected by jasmine...
69+
});
70+
});
71+
4372
it("should be able to get translations", () => {
73+
prepare();
74+
4475
translate.use("en");
4576

4677
// this will request the translation from the backend because we use a static files loader for TranslateService
@@ -61,6 +92,8 @@ describe("TranslateLoader (HttpClient)", () => {
6192
});
6293

6394
it("should trigger MarkerInterceptor when loading translations", () => {
95+
prepare();
96+
6497
translate.use("en").subscribe();
6598

6699
const req = http.expectOne("/assets/i18n/en.json");
@@ -70,6 +103,8 @@ describe("TranslateLoader (HttpClient)", () => {
70103
});
71104

72105
it("should be able to reload a lang", () => {
106+
prepare();
107+
73108
translate.use("en");
74109

75110
// this will request the translation from the backend because we use a static files loader for TranslateService
@@ -89,6 +124,8 @@ describe("TranslateLoader (HttpClient)", () => {
89124
});
90125

91126
it("should be able to reset a lang", (done: DoneFn) => {
127+
prepare();
128+
92129
translate.use("en");
93130
spyOn(http, "expectOne").and.callThrough();
94131

projects/http-loader/src/lib/http-loader.ts

Lines changed: 28 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,61 @@ import { TranslateLoader, TranslationObject } from "@ngx-translate/core";
44
import { Observable } from "rxjs";
55

66
export interface TranslateHttpLoaderConfig {
7-
prefix?: string;
8-
suffix?: string;
9-
enforceLoading?: boolean;
7+
prefix: string;
8+
suffix: string;
9+
enforceLoading: boolean;
10+
useHttpBackend: boolean;
1011
}
1112

12-
export const TRANSLATE_LOADER_CONFIG = new InjectionToken<TranslateHttpLoaderConfig>(
13-
"TRANSLATE_LOADER_CONFIG",
13+
export const TRANSLATE_HTTP_LOADER_CONFIG = new InjectionToken<Partial<TranslateHttpLoaderConfig>>(
14+
"TRANSLATE_HTTP_LOADER_CONFIG",
1415
);
1516

1617
@Injectable()
1718
export class TranslateHttpLoader implements TranslateLoader {
1819
private http: HttpClient = inject(HttpClient);
20+
private config: TranslateHttpLoaderConfig;
1921

20-
private prefix = "/assets/i18n/";
21-
private suffix = ".json";
22-
private enforceLoading = false;
22+
constructor() {
23+
this.config = {
24+
prefix: "/assets/i18n/",
25+
suffix: ".json",
26+
enforceLoading: false,
27+
useHttpBackend: false,
28+
...inject(TRANSLATE_HTTP_LOADER_CONFIG),
29+
};
2330

24-
public setPrefix(prefix: string): void {
25-
this.prefix = prefix;
26-
}
27-
28-
public setSuffix(suffix: string): void {
29-
this.suffix = suffix;
30-
}
31-
32-
public setClient(client: HttpClient): void {
33-
this.http = client;
34-
}
35-
36-
public setEnforceLoading(enforceLoading: boolean): void {
37-
this.enforceLoading = enforceLoading;
31+
this.http = this.config.useHttpBackend
32+
? new HttpClient(inject(HttpBackend))
33+
: inject(HttpClient);
3834
}
3935

4036
/**
4137
* Gets the translations from the server
4238
*/
4339
public getTranslation(lang: string): Observable<TranslationObject> {
44-
const cacheBuster = this.enforceLoading ? `?enforceLoading=${Date.now()}` : "";
40+
const cacheBuster = this.config.enforceLoading ? `?enforceLoading=${Date.now()}` : "";
4541

4642
return this.http.get(
47-
`${this.prefix}${lang}${this.suffix}${cacheBuster}`,
43+
`${this.config.prefix}${lang}${this.config.suffix}${cacheBuster}`,
4844
) as Observable<TranslationObject>;
4945
}
5046
}
5147

52-
function translateLoaderFactroy(
53-
client: HttpClient,
54-
prefix?: string,
55-
suffix?: string,
56-
enforceLoading?: boolean,
57-
): TranslateHttpLoader {
58-
const loader: TranslateHttpLoader = new TranslateHttpLoader();
59-
loader.setClient(client);
60-
loader.setEnforceLoading(enforceLoading ?? false);
61-
loader.setPrefix(prefix ?? "/assets/i18n/");
62-
loader.setSuffix(suffix ?? ".json");
63-
return loader;
64-
}
65-
6648
export function provideTranslateHttpLoader(
67-
prefix?: string,
68-
suffix?: string,
69-
enforceLoading?: boolean,
70-
): Provider {
49+
config: Partial<TranslateHttpLoaderConfig> = {},
50+
): Provider[] {
51+
const useBackend = config.useHttpBackend ?? false;
52+
7153
return [
7254
{
73-
provide: TranslateLoader,
74-
useFactory: () =>
75-
translateLoaderFactroy(inject(HttpClient), prefix, suffix, enforceLoading),
76-
deps: [HttpClient],
55+
provide: TRANSLATE_HTTP_LOADER_CONFIG,
56+
useValue: config,
7757
},
78-
];
79-
}
80-
81-
export function provideTranslateHttpLoaderFromHttpBackend(
82-
prefix?: string,
83-
suffix?: string,
84-
enforceLoading?: boolean,
85-
): Provider {
86-
return [
8758
{
8859
provide: TranslateLoader,
89-
useFactory: () =>
90-
translateLoaderFactroy(
91-
new HttpClient(inject(HttpBackend)),
92-
prefix,
93-
suffix,
94-
enforceLoading,
95-
),
96-
deps: [HttpBackend],
60+
useClass: TranslateHttpLoader,
61+
deps: [useBackend ? HttpBackend : HttpClient, TRANSLATE_HTTP_LOADER_CONFIG],
9762
},
9863
];
9964
}
Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,20 @@
1-
import { HttpClient, provideHttpClient } from "@angular/common/http";
1+
import { provideHttpClient } from "@angular/common/http";
22
import { ApplicationConfig, provideZoneChangeDetection } from "@angular/core";
33
import { provideRouter } from "@angular/router";
4-
import { TranslateLoader, provideTranslateService } from "@ngx-translate/core";
5-
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
4+
import { provideTranslateService } from "@ngx-translate/core";
5+
import { provideTranslateHttpLoader } from "@ngx-translate/http-loader";
66
import { routes } from "./app.routes";
77

8-
const httpLoaderFactory: (http: HttpClient) => TranslateHttpLoader = (http: HttpClient) =>
9-
new TranslateHttpLoader(http, "./i18n/", ".json");
10-
118
export const appConfig: ApplicationConfig = {
129
providers: [
1310
provideZoneChangeDetection({ eventCoalescing: true }),
1411
provideRouter(routes),
1512
provideHttpClient(),
16-
provideTranslateService({
17-
loader: {
18-
provide: TranslateLoader,
19-
useFactory: httpLoaderFactory,
20-
deps: [HttpClient],
21-
},
13+
provideTranslateService(),
14+
provideTranslateHttpLoader({
15+
prefix: "./i18n/",
16+
suffix: ".json",
17+
enforceLoading: true,
2218
}),
2319
],
2420
};

0 commit comments

Comments
 (0)