question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Default locale is lost when injecting intl service in another service

See original GitHub issue
  • I am on the latest ember-intl version
  • I have searched the issues of this repo and believe that this is not a duplicate

Environment

  • Ember Version: 3.7.2
  • Ember CLI Version: 3.7.1
  • Ember Intl Version: 3.5.0
  • Browser(s): FF, Chrome
  • Node Version: 10.12.0

Steps to Reproduce

After migrating from embr-i18n I got a weird issue. I set up a default locale as follows in application.js route:

import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';

export default Route.extend(ApplicationRouteMixin, {
  currentUser: service(),
  intl: service(),

beforeModel() {
    let locale = this.figureOutLocale();
    this.intl.setLocale(locale);
    return this._loadCurrentUser();
  },

figureOutLocale() {
    let locale = this.calculateLocale(this.intl.get('locales'));
    return locale;
  },

  calculateLocale(locales) {
    // whatever you do to pick a locale for the user:
    const language = navigator.languages[0] || navigator.language || navigator.userLanguage;

    return  locales.includes(language.toLowerCase()) ? language : 'en';
  }
});

I have just 2 translations files (en.yml and fr.yml) and it seems to work as needed in all the the views exept the one using Constants service that I defined as follows:

#services/constants.js

import Service from '@ember/service';
import { inject as service } from '@ember/service';

export default Service.extend({
    intl: service('intl'),

    init() {
      this._super(...arguments);
      console.log('IN CONSTANTS service locale: ' + this.intl.get('locale'));
      this.set('states',
        [
          {id: 'open', name: this.intl.t('states.open')},
          {id: 'closed', name: this.intl.t('states.closed')},
          {id: 'divided', name: this.intl.t('states.divided')}
        ]
      );
      this.set('days',
        [
          {day: 'monday', name: this.intl.t('weekdays.monday')},
          {day: 'tuesday', name: this.intl.t('weekdays.tuesday')},
          {day: 'wednesday', name: this.intl.t('weekdays.wednesday')},
          {day: 'thursday', name: this.intl.t('weekdays.thursday')},
          {day: 'friday', name: this.intl.t('weekdays.friday')},
          {day: 'saturday', name: this.intl.t('weekdays.saturday')},
          {day: 'sunday', name: this.intl.t('weekdays.sunday')}
        ]
      );
      this.set('categories',
        [
          'DECATHLON',
          'SEASONAL',
          'ESSENTIAL',
          'WORKSHOP',
          'BRAND_SPECIALIST',
          'CITY'
        ]
      )
    }

});

Weird but, the above console log statement displays a wrong locale:

IN CONSTANTS service locale: en-us

instead of just en or fr(this is the case if I put a debug point in application.js route). So the translated states values are not displayed in the drop-down lists:

screenshot 2019-01-29 at 17 35 39

Here is the template code to display the drop-down list:

#templates/components/weekday-row.hbs

<div class="col-sm-2">
    <select
      class="form-control"
      onchange={{action
        "selectState"
        value="target.value"
      }}
    >
      {{#each states as |state|}}
        <option value={{state.id}} selected={{eq state.id weekday.state}}>{{state.name}}</option>
      {{/each}}
    </select>
  </div>

And here is how I initialize the states in the component JS file:

#components/weekday-row.js

import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';

export default Component.extend({
  intl:      service('intl'),
  constants: service(),
  weekday:   null,
  state:     null,
  states:    [],
  tagName:   '',

  init() {
    this._super(...arguments);
    this.set('states', this.get('constants.states'));
  },
...

What am I missing here ? Thank you.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
belgoroscommented, Jan 31, 2019

Thanks to the help I got from Discord (special thanks to @Lux and @Windivs), I got it working by using a computed property:

import Service from '@ember/service';
import { computed } from '@ember/object';
import { inject as service } from '@ember/service';

export default Service.extend({
  intl: service(),
...
  states: computed('intl.locale', function(){
    return  [
      {id: 'open', name: this.intl.t('states.open')},
      {id: 'closed', name: this.intl.t('states.closed')},
      {id: 'divided', name: this.intl.t('states.divided')}
    ];
  }),
  
  days: computed('intl.locale', function(){
    return [
      {day: 'monday', name: this.get('intl').t('weekdays.monday')},
      {day: 'tuesday', name: this.get('intl').t('weekdays.tuesday')},
      {day: 'wednesday', name: this.get('intl').t('weekdays.wednesday')},
      {day: 'thursday', name: this.get('intl').t('weekdays.thursday')},
      {day: 'friday', name: this.get('intl').t('weekdays.friday')},
      {day: 'saturday', name: this.get('intl').t('weekdays.saturday')},
      {day: 'sunday', name: this.get('intl').t('weekdays.sunday')}
    ];
  })  
});

I set up the locale for intl service in application route as described earlier:

beforeModel() {
    let locale = this.figureOutLocale();
    this.intl.setLocale(locale);
    return this._loadCurrentUser();
  },

Hope this helps. Thank you for your time !

1reaction
belgoroscommented, Jan 30, 2019

Doing like that still fails because init method in constants.js is called before its setIntlLocale(locale): screenshot 2019-01-30 at 11 05 00

Read more comments on GitHub >

github_iconTop Results From Across the Web

Alternative way to supply default messages? #557 - GitHub
I currently am storing all translations as a json files (one file per locale e.g. en-US.json, de.json) which then are then loaded and...
Read more >
Could not find required `intl` object. <IntlProvider> needs to ...
IntlProvider gets the locale and translated strings. Parent components have been injected with Intl: Page.propTypes = { intl: intlShape.
Read more >
Extending react-intl with your own markup - Keypup
Create your own wrapper to extend react-intl with your own context and markup language. TL;DR; Instead of using the default FormattedMessage ...
Read more >
How to translate your React app with react-intl / FormatJS
It expects the current locale as property. For the moment we're setting it to a fixed language, later we will determine the user's...
Read more >
Localize your app - Android Developers
If an app is missing even one default resource, it doesn't run on a device that is set to an unsupported locale. For...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found