Skip to content

Commit 6af879d

Browse files
committed
fix(i18n): set now does a deep merge
1 parent 0cb4c51 commit 6af879d

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

src/i18n/i18n.service.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,30 @@ export const replace = (subject, variables) => subject.pipe(
3434
})
3535
);
3636

37+
// custom deep object merge
38+
const merge = (target, ...objects) => {
39+
for (const object of objects) {
40+
for (const key in object) {
41+
if (object.hasOwnProperty(key)) {
42+
// since we're dealing just with JSON this simple check should be enough
43+
if (object[key] instanceof Object) {
44+
if (!target[key]) {
45+
target[key] = {};
46+
}
47+
// recursivly merge into the target
48+
// most translations only run 3 or 4 levels deep, so no stack explosions
49+
target[key] = merge(target[key], object[key]);
50+
} else {
51+
target[key] = object[key];
52+
}
53+
}
54+
}
55+
}
56+
return target;
57+
};
58+
3759
/**
38-
* The I18n service is a minimal internal service used to supply our components with translated strings.
60+
* The I18n service is a minimal internal singleton service used to supply our components with translated strings.
3961
*
4062
* All the components that support I18n also support directly passed strings.
4163
* Usage of I18n is optional, and it is not recommended for application use (libraries like ngx-translate
@@ -54,7 +76,8 @@ export class I18n {
5476
* @param strings an object of strings, should follow the same format as src/i18n/en.json
5577
*/
5678
public set(strings) {
57-
this.translationStrings = Object.assign({}, EN, strings);
79+
this.translationStrings = merge({}, EN, strings);
80+
// iterate over all our tracked translations and update each observable
5881
const translations = Array.from(this.translations);
5982
for (const [path, subject] of translations) {
6083
subject.next(this.getValueFromPath(path));

src/i18n/i18n.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,11 @@ describe("i18n service", () => {
6161
done();
6262
});
6363
});
64+
65+
it("should keep the default translation strings", () => {
66+
service.set({ "BANNER": { "TEST": "TEST" } });
67+
68+
expect(service.get().BANNER.CLOSE_BUTTON).toBe(EN.BANNER.CLOSE_BUTTON);
69+
expect(service.get().BANNER.TEST).toBe("TEST");
70+
});
6471
});

0 commit comments

Comments
 (0)