kazupon/vue-i18n

Formatting is broken when switching language

Open

#983 opened on Aug 28, 2020

View on GitHub
 (11 comments) (1 reaction) (0 assignees)JavaScript (7,181 stars) (886 forks)batch import
Status: In Progresshelp wanted

Description

vue & vue-i18n version

Vue version: 2.6.11 Vue-i18n version: 8.18.2

Reproduction Link

https://codesandbox.io/s/elastic-shockley-wjw0z

Steps to reproduce

When using a formatter like the one provided by the official documentation, and switching locale, the formatter is not aware of this change.

(INFO: I tried this version of the formatter but it seems broken : TypeError: fn(...).map is not a function)

So I added this method to the formatter:

// Formatter.js
changeLocale(locale) {
  this._locale = locale;
  this._formatter = new MessageFormat(locale);
}

Then I can use this method when switching locale:

// App.vue
switchLocale(locale) {
  this.$i18n.locale = locale;
  this.$i18n.formatter.changeLocale(locale);
},

I don't know if it's the proper way to do this, but it solves partially my problem. Maybe there is another way to achieve this?

BUT, there's still a bug, formatted messages doesn't update when the translation string is exactly the same in both languages! Example:

const translations = {
  fr: {
    test: {
      number: {
        first: "Mon nombre est {myNumber, number, integer}",
        second: "{myNumber, number, integer}" // exact same string in 'en' and 'fr'
      },
      date: {
        first: "Ma date est {myDate, date, medium}",
        second: "{myDate, date, medium}" // exact same string in 'en' and 'fr'
      }
    }
  },
  en: {
    test: {
      number: {
        first: "My number is {myNumber, number, integer}",
        second: "{myNumber, number, integer}" // exact same string in 'en' and 'fr'
      },
      date: {
        first: "My date is {myDate, date, medium}",
        second: "{myDate, date, medium}" // exact same string in 'en' and 'fr'
      }
    }
  }
};

What is Expected?

When I use translation strings in a template and I switch locale, I expect the strings to be formatted in the chosen locale.

Number first

  • template: {{ $t('test.number.first', { myNumber: 2440 }) }}
  • expected output:
    • en: My number is 2,440 ✔️
    • fr: Mon nombre est 2 440 ✔️

Number second

  • template: {{ $t('test.number.second', { myNumber: 2440 }) }}
  • expected output:
    • en: 2,440 ✔️
    • fr: 2 440

Date first

  • template: {{ $t('test.date.first', { myDate: '2020-08-28 13:47:38+02:00' }) }}
  • expected output:
    • en: My date is Aug 28, 2020 ✔️
    • fr: Ma date est 28 août 2020 ✔️

Date second

  • template: {{ $t('test.date.second', { myDate: '2020-08-28 13:47:38+02:00' }) }}
  • expected output:
    • en: Aug 28, 2020 ✔️
    • fr: 28 août 2020

What is actually happening?

Number second

  • actual output:
    • fr: 2,440

Date second

  • actual output:
    • fr: Aug 28, 2020

As I said before, the concerned translation strings are those that are exactly the same in 'en' and 'fr', so I guess it could be a cache issue?

Any idea how to solve this?

Contributor guide