Are dots allowed in keys in ngx-translate

Viewed 36

I have a problem in the codebase that I'm working on right now related to keys with dots.

Basically, the i18n JSON contains something like:

{
  a: {
    title: 'Title for a'
  },
  b: {
    title: 'Title for b'
  },
  'a.b': {
    title: 'Title for a.b'
  }
}

In the html we are accessing it

{{ 'a.title' | translate }}

In short, these are the results for the existing keys

key Result Works
a {title: 'Title for a'} ✅
a.title Title for a ✅
b {title: 'Title for b'} ✅
b.title Title for b ✅
a.b undefined ❌
a.b.title undefined ❌

Tried to search in the documentation and the Github issues but there's nothing that points that this is allowed/disallowed.


Furthermore, I debugged the code and saw that the method responsible to get the value for a given key is getValue in translate.parser.ts.

This specific method isn't able to deal with cases where there's a key with dots for which there's another key with the initial part of said key. For example, if we have two keys 'a' and 'a.b' but 'a' is a string then the method works. If in this example 'a' was an object then it doesn't work.

I also reckon that it's hard to implement since we can have a case like this:

{
  a: {
    b: {
       title: 'Title for a'
    }
  },
  'a.b': {
    title: 'a.b title'
  }
}

If you pass the following {{ 'a.b.title' | translate }} which one would be translated?


My possibilities are:

  1. Replace all keys with dots by underscores or something else
  2. Create parser that extends the TranslateDefaultParser and re-implements the getValue method
2 Answers

by default while using {{ 'a.b.title' | translate }} ngx-translate search this

{
  a: {
    b: {
       title: 'Title for a'
    }
  }
}

To answer my own post, YES dots are allowed in keys BUT it can cause you trouble easily if you have composite keys.

My solution was to flatten all translations which makes the underlying code O(1) to get each key and allows us to use dots even in composite keys.

Flattening all translations means that the following:

{
    a: {
       b: {
          title: 'Title for b',
          label: 'Label for b'
       }
   }
}

Becomes:

'a.b.title': 'Title for b'
'a.b.label': 'Label for b'
Related