Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

translate returns an object instead of a string #1

Closed
ppet opened this issue Jun 12, 2014 · 5 comments
Closed

translate returns an object instead of a string #1

ppet opened this issue Jun 12, 2014 · 5 comments

Comments

@ppet
Copy link

ppet commented Jun 12, 2014

when used outside the return statement of the React class render function, the react-translate-component's translate function returns an object where a string should be returned.
code snippet within a React.creatClass:
render:function() {
var menusLns = this.getFooterMenu(); //getting a json file that describes my menus
var i, j;
var menus = [];
var content;

    for (i = 0; i < menusLns.length; ++i) {
        var Menu = {};
        Menu.title = menusLns[i].id;
       Menu.items = "";
        for (j = 0; j < menusLns[i].menuitem.length; ++j) {
            var tagTitle = menusLns[i].menuitem[j].value;
            console.log("item tagTitle = " + tagTitle); // Ok
            var text = this._e("gui", tagTitle); // we are not within the return statement...

// this._e comes from a mixin lib in which we have _e: require('react-translate-component').translate,
// this syntax works nicely in another react component, but within its return statement
console.log("item text = " + text); // KO: object Object
var link = menusLns[i].menuitem[j].link;
var item = '\u003cli\u003e\u003ca title="' + tagTitle + '" href="' + link + '"\u003e' + text + '\u003c/a\u003e\u003c/li\u003e\n';
console.log("menu item: " + item);
Menu.items += item;
}
menus.push(Menu);
}

    return (
        <  ....  >
    );
}
@martinandert
Copy link
Owner

You are using it wrong. React-Translate-Component's translate function is just a convenience function that mimics the invocation of Counterpart's exported method. translate returns an "instance" of the React component. So instead of this

var Translate = require('react-translate-component');

// in render function
return React.DOM.li(null, Translate(null, 'my.translation.key'));

you can do it a bit shorter this way

var t = require('react-translate-component').translate;

// in render function
return React.DOM.li(null, t('my.translation.key'));

If you need a translated string to be returned, use Counterpart's method. Counterpart is a peer dependency of React-Translate-Component und used internally in its render function.

var _t = require('counterpart');
_t('my.translation.keys') // => 'a string'

@andresgutgon
Copy link

Hi, in my case I need transtation to be a string to use as a HTML attribute. Look at i18n_placeholder

This is my component:

  render: function () {
    var i18n_placeholder = counterpart.translate('foo.email.placeholder');
    return (
      <div>
          <input type="email" placeholder={i18n_placeholder} />
      </div>
    );
  },

The problem

If I implement a locale swicher this way
image

When locale is changed by the user, Counterpart translations are not changed because are not React Components.

Question

How can I update counterpart translations when user select locale in switcher component?

Note

Switcher component is the same you use in your example

@martinandert
Copy link
Owner

How can I update counterpart translations when user select locale in switcher component?

You could listen to Counterpart's locale change event in your component's componentDidMount lifecycle method. Example (untestet):

var MyComponent = React.createClass({
  /* ... */

  componentDidMount: function() {
    counterpart.onLocaleChange(this.localeChanged);
  },

  componentWillUnmount: function() {
    counterpart.offLocaleChange(this.localeChanged);
  },

  localeChanged: function(newLocale) {
    this.setState({ 
      placeholder: counterpart.translate('foo.email.placeholder')
    });
  },

  render: function () {
    var i18n_placeholder = this.state.placeholder;

    return (
      <div>
        <input type="email" placeholder={i18n_placeholder} />
      </div>
    );
  },
});

@andresgutgon
Copy link

Thank you @martinandert that worked great

@neemzy
Copy link

neemzy commented Dec 1, 2015

Thanks for the tip! Might be useful to put that somewhere in the README (FAQ or so), as it is a quite common use case.

In my case, I built on top of your tip to have Counterpart.onLocaleChange set the current locale in the state of my root component. When the locale changes, it rerenders itself and all its children, thus triggering Counterpart's native translate function again with the current locale. Any thoughts? Would you fear a performance pitfall with such a global solution?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants