Jonas Knobloch Jonas Knobloch - 3 months ago 96
JSON Question

Polymer: iron-selector issue

Because I failed to create a working plunker I uploaded the test elemet to my private webserver. You can test the code below at thevplan.de/x-test.html. The JSON file is located at thevplan.de/getMenu.json.

Code:

x-test.html

<!DOCTYPE html>
<html>
<head>
<title>x-test 4</title>
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="src/vplan-imports.html">
</head>
<body>

<dom-module id="x-test">
<template>
<iron-ajax
auto
id="getMenu"
url="getMenu.json"
handle-as="json"
on-response="handleResponse"
last-response="{{lastResponse}}"></iron-ajax>

<paper-dropdown-menu label="Day">
<paper-listbox class="dropdown-content" selected="{{selectedDateIndex}}">
<template id="dayList" is="dom-repeat" items="[[lastResponse]]">
<paper-item>[[item.day]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>

<br>

<paper-dropdown-menu label="Class">
<paper-listbox id="classMenu" class="dropdown-content" selected="{{selectedClassValue}}"
attr-for-selected="value">
<template is="dom-repeat" items="[[targetArray]]">
<paper-item value="[[item]]">[[item]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>

<br>
<br>

<span>selectedClassValue: [[selectedClassValue]]</span>

</template>
</dom-module>

<script>

Polymer({
is: 'x-test',
ready: function () {

},
properties: {
lastResponse: {
type: Array
},
targetArray: {
type: Array,
computed: 'computeTargetArray(selectedDateIndex, lastResponse)',
},
selectedDateIndex: {
type: Number,
value: 0
},
selectedClassValue: {
type: String
},
selectedClassValueOld: {
type: String
}
},
observers: [
'generateClassSelection(targetArray)'
],

handleResponse: function () {
//console.log('x-test: AJAX response ready');
},

computeTargetArray: function (selectedDateIndex, lastResponse) {
this.selectedClassValueOld = this.selectedClassValue;
this.selectedClassValue = false;
return (lastResponse[selectedDateIndex].lessons);
},

generateClassSelection: function (targetArray) {
console.log('x-test: targetArrayChanged');
if (targetArray.indexOf(this.selectedClassValueOld) != -1) {
Polymer.dom(this.root).querySelector('#classMenu').select(this.selectedClassValueOld);
console.log('x-test: selectedClassValueOld used');
} else {
Polymer.dom(this.root).querySelector('#classMenu').select(targetArray[0]);
console.log('x-test: first class selected');
}

}
});
</script>

<x-test></x-test>


</body>
</html>


getMenu.json

[
{
"date": "2016-08-15",
"day": "Monday",
"lessons": [
"08b",
"08c",
"08d",
"09b",
"09c",
"09e",
"10b",
"11"
]
},
{
"date": "2016-08-16",
"day": "Tuesday",
"lessons": [
"06c",
"06d",
"07a",
"07b",
"09a",
"09b",
"09c",
"09d",
"09e",
"10a",
"10c",
"10d",
"11",
"12"
]
},
{
"date": "2016-08-17",
"day": "Wednesday",
"lessons": [
"06a",
"06b",
"06d",
"07a",
"07d",
"08b",
"08c",
"08d",
"09c",
"09e",
"10a",
"10d",
"11",
"12"
]
},
{
"date": "2016-08-18",
"day": "Thursday",
"lessons": [
"05a",
"06c",
"06d",
"07a",
"08c",
"09d",
"09e",
"10a"
]
}
]


The second menu becomes blank if you switch to a target array with the same amount of entries. If you switch from Monday to Tuesday everything works fine. But if you switch from Monday to Thursday the value is not visible inside the dropdown menu. The menu array for Tuesday has more entries than the array for Monday. But the array for Thursday contains the same amount of entries as the array for Monday.

Answer

I think you are running into a timing issue.

You should either wait until dom-repeat finished rendering by waiting for the dom-change event (see the docs)

<template is="dom-repeat" items="[[targetArray]]" on-dom-change="generateClassSelection">
</template

Or you can use this.async to defer setting the selected value of your paper-listbox:

generateClassSelection: function (targetArray) {
    console.log('x-test: targetArrayChanged');
    this.async(function() {
      if (targetArray.indexOf(this.selectedClassValueOld) != -1) {
        Polymer.dom(this.root).querySelector('#classMenu').select(this.selectedClassValueOld);
        console.log('x-test: selectedClassValueOld used');
      } else {
        Polymer.dom(this.root).querySelector('#classMenu').select(targetArray[0]);
        console.log('x-test: first class selected');
      }
}