app-localize-behavior
app-localize-behavior copied to clipboard
How can i use Localize in ready Function ?
Hi :)
Localization behavior is working fine for me, but i don't know if i can use it in a ready function and how. For exemple, for a login form, i want to show a toast with different informations in two language.
If login are good : {{localize('login_succeeded', 'pseudo', event.detail.response.pseudo)}}
If login are wrong : {{localize('login_failed')}}
If error : {{localize('login_error')}}
My code :
<div class="container flex-center-justified flex-center-align">
<div class="inner-container">
<img src="../images/myApp.png" alt="myApp">
<h2>myApp</h2>
<form is="iron-form" method="post" action="../API/v1/index.php/login" id="loginForm">
<paper-input type="text" name="pseudo" label="{{localize('login_pseudo')}}" no-label-float required></paper-input>
<paper-input type="password" name="password" label="{{localize('login_password')}}" no-label-float required></paper-input>
<paper-button noink on-tap="_submit">{{localize('login_submit')}}</paper-button>
<div class="output"></div>
</form>
</div>
</div>
<paper-toast id="toast"></paper-toast>
</template>
<script>
Polymer({
is: 'my-login',
behaviors: [
Polymer.AppLocalizeBehavior
],
properties: {
language: {
value: 'fr',
type: String
}
},
attached: function() {
this.loadResources(this.resolveUrl('locales.json'));
},
ready: function() {
var loginForm = this.$.loginForm;
var request = loginForm.request;
var toast = this.$.toast;
loginForm.addEventListener('iron-form-response', function(event) {
console.log("Form Error: ",event.detail.response.error);
if (event.detail.response.error) {
message = localize('login_failed');
toast.show({text: message, duration: 5000});
} else {
message = localize('login_succeeded', 'pseudo', event.detail.response.pseudo);
toast.show({text: message, duration: 5000});
}
});
loginForm.addEventListener('iron-form-error', function(event) {
message = localize('login_error');
toast.show({text: message, duration: 5000});
});
},
_submit(event) {
Polymer.dom(event).localTarget.parentElement.submit();
}
});
</script>
locales.json
{
"en": {
"login_succeeded": "Greetings {pseudo} !",
"login_failed": "Incorrect IDs.",
"login_error": "Oops, an error occurred !",
"login_pseudo": "Nickname",
"login_password": "Password",
"login_submit": "Connection"
},
"fr": {
"login_succeeded": "Salutations {pseudo} !",
"login_failed": "Identifiants incorrects.",
"login_error": "Oups, une erreur est survenue !",
"login_pseudo": "Surnom",
"login_password": "Mot de passe",
"login_submit": "Connexion"
}
}
Thanks. Greetings Loïc.
I think it should be this.localize('login_failed')
, not just localize('login_failed')
.
However I got it working from inside regular functions only, not from inside lifecycle functions like ready
or even attached
. Not sure why, though. Maybe this has something to do with computed properties.
You can use it like that:
this.async(function(){
this.localize('translation')
},100);
@hyyan Thanks, this looks like an acceptable solution most of the times. However it's still not clear why computed functions are not available in lifecycle functions. It seems that Polymer documentation is lacking on this topic. :disappointed:
Thanks guys !
I will try it later. In the case where i want to call a function inside the ready function or a normal function, how it's work ?
For example : See the showToast() function
<script>
Polymer({
is: 'my-login',
ready: function() {
this.async(function() {
this.showToast("This is a message...");
},100);
},
otherFunction: function() {
this.showToast("This is a message...");
},
showToast: function(message) {
toast.show({text: message, duration: 5000});
}
});
</script>
Thanks, Loïc.
Just replace the text message with this.localize('myKey');
Also, about the function you're passing to async, you should either bind it to this
or make it an arrow function.
Hi guys !
I tried this after your recommendation :
toastMessage.show({horizontalAlign: 'right', verticalAlign: 'top', duration: 5000, text: this.async(function() { this.localize('login_failed'); },100)});
And I still have :
Uncaught ReferenceError: this.localize is not defined(…)
Loïc.
@SheanYu Try something like this
this.async((function() {
toastMessage.show({
horizontalAlign: 'right',
verticalAlign: 'top',
duration: 5000,
text: this.localize('login_failed')
});
}).bind(this), 100);
@davebaol Same error...
Note that i'm in the ready function :
ready: function() {
...
loginForm.addEventListener('iron-form-response', function(event) {
if (event.detail.response.error) {
this.async((function() {
toastMessage.show({
horizontalAlign: 'right',
verticalAlign: 'top',
duration: 5000,
text: this.localize('login_failed')
});
}).bind(this), 100);
} else {
...
}
});
...
},
@SheanYu
Actually, that code is executed out of the ready function since it's an event handler.
You just have to bind the event handler to this
like that (function(event) {...}).bind(this)
@davebaol
With this :
ready: function() {
...
loginForm.addEventListener('iron-form-response', function(event) {
if (event.detail.response.error) {
this.async((function() {
toastMessage.show({
horizontalAlign: 'right',
verticalAlign: 'top',
duration: 5000,
text: this.localize('login_failed')
});
}).bind(this), 100);
} else {
...
}
}).bind(this);
...
},
I got this error :
Uncaught TypeError: Cannot read property 'bind' of undefined(…)
ready @ my-login.html:165
_invokeBehavior @ polymer-micro.html:455
_doBehavior @ polymer-micro.html:445
_readySelf @ polymer-mini.html:88
_ready @ polymer-mini.html:75
_tryReady @ polymer-mini.html:60
_initFeatures @ polymer.html:4053
createdCallback @ polymer-micro.html:202
window.Polymer @ polymer-micro.html:65
(anonymous function) @ my-login.html:124
@SheanYu
Well, you're binding this
to nothing. This should make it work
loginForm.addEventListener('iron-form-response', (function(event) {
...
}).bind(this));
I'm having problems too with localize in the ready event. It says localize is not a function.
The (ugly) async approach works most of the times, but sometimes 100ms is not enough and it fails. I know I can increase the timeout, but I think it would be better to have a solution to make it always work.
I understand that resources may not yet be loaded, but I expect it to be another kind of error...
I understand that resources may not yet be loaded, but I expect it to be another kind of error...
I don't think it's a matter of resources not loaded yet
@davebaol Me neither, I think it has something to do with the computed properties and the way Polymer handles them. But, why not make localize a regular function?
@lluisgener
Because being localize a computed property when language or resources change all [[localize(...)]]
are dynamically re-calculated.
@davebaol I see. But I guess only bound localizations are re-calculated, not the ones invoked programatically. So maybe a good solution would be to keep the computed property as is, and also have a regular function which should be the recommended in a no-bound usage.
Or make the Polymer team invoke the ready event when computed properties have been initialized, if it's possible...
It seems you can work around this issue using computed properties, like this:
Polymer({
properties: {
errorMessage: {
type: String,
computed: '_initErrorMessage(localize)'
},
},
_initErrorMessage: function(localize) {
return localize('myMsg');
}
});
So is there even any way of calling localize from within a polymer element, indifferent of in the ready() function or any other element function?
As it is usual to process UI texts in functions, it is necessary to grab translations in the code and then pass it to the UI.
Regards, Michael
@Mika83AC look at @craPkit post. It worked flawlessly for me. But you need to tweak a little your code to correctly use computed properties.
Regards.
Hm... sure, this is possible but creates an immense overhead (code size, complexity ...). This is just not possible for larger applications and can't be the solution the Polymer team wants to see.
So I really hope they have another solution for us. :)
I think that it's the way to go, because localize is a computed method to be able to change language during execution, and I think the better way to do it is with a calculated method, as it is.
** Removed because of completely bullshit, sorry :D **
Doesn't this.localize('translationKey')
work outside of ready()
anyway?
I manage to resolve this way
<link rel="import" href="../bower_components/app-localize-behavior/app-localize-behavior.html">
<dom-module id="x-custom">
<template>
<span> [[_greetings(name, localize)]]</span>
</template>
<script>
Polymer({
is: 'x-custom',
behaviors: [
Polymer.AppLocalizeBehavior
],
properties: {
name: String,
language: { type: String, value: 'zh-CN' }
},
attached: function() {
this.loadResources(this.resolveUrl('locales.json'));
},
_greetings: function(name, localize) {
return localize('hello')+ ' ' + name;
}
});
</script>
</dom-module>