Open sangron opened 7 years ago
Have you tried loading the resources later, in ready
or connectedCallback
? constructor
is way before Polymer stamped the properties, so it makes sense why resources
is not populated
Edit 27.06.2017: The issue happen when you don't lazy load your pages.
I have the same problem than @sangron: undefined resources attribute.
I implemented his code (I changed only names) to see what do we get when loading in constructor
, ready
in connectedCallback
.
I used the event app-localize-resources-loaded to know when the resources are really loaded. I added few traces in the console to have an idea of the actual sequence:
FormatMixin:
connectedCallback() {
super.connectedCallback();
console.log("Add a listener to app-localize-resources-loaded");
this.addEventListener('app-localize-resources-loaded', function(e){
console.log('app-localize-resources-loaded', this.resources);
}.bind(this));
console.log('Calling this.loadResources()...');
this.loadResources(this.resolveUrl('/static/locales.json'));
}
static get properties() {
// ...
}
getLabel(a) {
console.log('getLabel() is called... this.resources is', this.resources);
var args = Array.prototype.slice.call(arguments);
var prop = args.join('');
var label = prop;
if(this.localize)
label = this.localize(prop);
return label;
}
constructor
mi-localization.html:12 Add a listener to app-localize-resources-loaded mi-localization.html:17 Calling this.loadResources()... mi-localization.html:39 getLabel() is called... this.resources is undefined mi-localization.html:14 app-localize-resources-loaded Object {es: Object}
I added a <pre>{{resources}}</pre>
so I can see if the binding works even though the call is performed in the constructor. I see the [Object object]
rendered as expected because the result of the iron-ajax
takes a bit of time and everything is ready-to-go when the response arrives.
So in my opinion the properties will be stamped in most of cases.
ready
getLabel() is called... this.resources is undefined mi-localization.html:12 Add a listener to app-localize-resources-loaded mi-localization.html:17 Calling this.loadResources()... mi-localization.html:14 app-localize-resources-loaded Object {es: Object}
The compound binding call the localize method even before we do request for the resources. The problem is then "how to delay the compound binding so we can trigger it when the resources arrived?"
connectedCallback
getLabel() is called... this.resources is undefined mi-localization.html:12 Add a listener to app-localize-resources-loaded mi-localization.html:17 Calling this.loadResources()... mi-localization.html:14 app-localize-resources-loaded Object {es: Object}
The same...
To get it to work for sure, I use an intermediary private property in the compound binding instead of the synchronous call to the localize
method.
I feed this private property in the listener of app-localize-resources-loaded.
class OrdhusetApp extends LocalizationMixin(Polymer.Element) {
static get is() { return 'ordhuset-app'; }
static get properties() {
return {
__translation: {
type: String,
value: 'no translation :('
}
};
}
ready() {
this.addEventListener('app-localize-resources-loaded', function(e){
this.__translation = this.getLabel('app.title');
}.bind(this));
// Call the super.ready method after having set the listener
// so i'm sure it is here before the resources arrive.
super.ready();
}
}
And the compound binding:
<div>Test translation: [[__translation]]</div>
Result:
It works... But it's not really convenient!
@notwaldorf What is the status of this issue? Still not working here.
The issue is trying to load the resources globally in the app using load resources. Child components load and are created before the network request is returning. When the network request does finally return the _computedLocalize function never gets triggered in the child component as the resources have been updated outside of the child component so it is not aware of the changes. One potential solution could be that any time _computeLocalize gets called and there is an existing ajax request to listen for the response of it and update then. That way all localizations should be triggered when the one ajax response occurs.
I find myself having to do this in all localized elements:
<dom-module id="my-element">
<template>
<style>...</style>
<!-- Don't render until I18N resources are ready. -->
<dom-if if="{{resources}}">
<template>
... all of my element's DOM...
</template>
</dom-if> <!-- resources -->
</template>
<script>
class MyElement extends Polymer.mixinBehaviors([Polymer.AppLocalizeBehavior], ReduxActionsMixin(Polymer.Element)) {
...
</script>
</dom-module>
This waits to construct any of the element's DOM until {{resources}} is non-empty/truthy. If I don't do this, I get localize() called before the resources are ready.
I'm using PolymerElements/app-localize-behavior 2.0.1.
Description
Creating a mixin/behavior to be extended by multiple elements, the
this.loadResources('/src/locales.json')
is not setting theresources
property, sothis.localize('res.key')
returnsundefined
Expected outcome
resources
being set with the object in the json fileActual outcome
resources
staysundefined
Steps to reproduce
formats-behavior.html
then in file legal-docs.html
and locales.json
I have debugged it and the constructor is being called, the json file is being loaded, confirming in the network tab in the devtools. But the
resource
property is not set. I have another app with this same pattern without problems, but it is using an earlier version of Polymer 2, so I am just guessing that something broke in recent changes.Browsers Affected