@@ -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 ) ) ;
0 commit comments