Polymer 1.0 deep path array binding - polymer

I am trying to get the following to work. It initially of course renders the content of parentItems, but when changing it, the template looping over the parentItems is not invoked. I have looked at the notifyPath, but am not sure if this is the right direction
<!doctype html>
<html>
<head>
<script src='bower_components/webcomponentsjs/webcomponents-lite.min.js'></script>
<link rel='import' href='bower_components/paper-button/paper-button.html'>
</head>
<body>
<dom-module id='my-element'>
<template>
<template is='dom-repeat' items='{{parentValues}}'>
<template is='dom-repeat' items='{{item.childValues}}'>
<div>{{item.value}}</div>
</template>
</template>
<paper-button on-tap='click'>click me</paper-button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-element',
properties: {
parentValues: {
type: Array,
value: function() { return [ { childValues: [ { value: 'original value' } ] } ]}
}
},
click: function() {
this.parentValues[0].childValues[0].value = 'new value';
}
});
</script>
<my-element></my-element>
</body>
</html>
How can I get it to work?
Thanks a million :-)

I believe the issue, which #jeanPokou solved was that you need to use the 'this.set(Object, New Value)' to set the value on the nested object.
You can check this video from the 'Ask Polymer' series to learn more about why it doesn't update nested values: https://youtu.be/0GxteaIaj2Q

You need to use dom-repeat with as scope in your binding, and notifyPath to bubble up change to your array when changed
<!doctype html>
<html>
<head>
<script src='bower_components/webcomponentsjs/webcomponents-lite.min.js'></script>
<link rel='import' href='bower_components/paper-button/paper-button.html'>
</head>
<body>
<dom-module id='my-element'>
<template is='dom-repeat' items='{{parentValues}}' as ="parent">
<template is='dom-repeat' items='{{parent.childValues}}' as="child">
<div>{{child.value}}</div>
</template>
</template>
<paper-button on-tap='click'>click me</paper-button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-element',
properties: {
parentValues: {
type: Array,
value: function() { return [ { childValues: [ { value: 'original value' } ] } ]}
}
},
click: function() {
// notify path to the properties using the polymer syntax
this.set('parentValues.0.childValues.0.value','changed value');
}
});
</script>
<my-element></my-element>
</body>
</html>

Related

Array value initialized in element doesn't show at the mediator level

Not sure what I'm doing wrong, but I expect to see the length of an array I've initialized. However, I see an empty value instead, when I access the data at 'mediator' level.
This code is also in a jsbin: http://jsbin.com/wujaruy/edit?html,output
<!doctype html>
<head>
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/">
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<dom-module id="x-container">
<template>
<!-- doesn't show the expected value of '3' -->
<div>In container; # of items:[[listItems.length]]</div>
<x-list listItems="{{listItems}}"></x-list>
</template>
<script>
Polymer({
is: 'x-container'
});
</script>
</dom-module>
<dom-module id="x-list">
<template>
<div>In x-list 1; # of items:[[listItems.length]]</div>
</template>
<script>
Polymer({
is: 'x-list',
properties: {
listItems: {type: Array, value: [1,2,3], notify: true}
}});
</script>
</dom-module>
<x-container listItems="{{listItems}}"></x-container >
</body>
Figured it out; I got bitten by the upper-case issue. Changing
<x-list listItems="{{listItems}}"></x-list>
to
<x-list list-items="{{listItems}}"></x-list>
fixes the issue

Polymer 1.x: accessing element within dom-if

Here is my JSBin
Click on the "First Name: James" text.
I have an input element within dom-if. In an event, I am making dom-if to pass and so the element will come into existence but I cannot access the input element immediately after making the dom-if condition pass.
May be I need to know when the dom-if is actually evaluated and why the element does not exist even if the condition has become true.
<!doctype html>
<head>
<meta charset="utf-8">
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="iron-form/iron-form.html" rel="import">
<link href="paper-input/paper-input.html" rel="import">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<template is="dom-if" if="{{!editMode}}">
<span id="name" on-tap="_makeEditable">{{name}}: {{value}}</div>
</template>
<template is="dom-if" if="{{editMode}}">
<paper-input id="input" label="{{name}}" value="{{value}}"></paper-input>
</template>
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
editMode: {
type: Boolean,
value: false
},
name: {
type:String,
value:"First Name"
},
value: {
type:String,
value:"James"
}
},
_makeEditable: function() {
this.editMode = true;
//how to find the input element here
//this.$$('#input').querySelector("input").focus();
//this.$.input.querySelector("input").focus();
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
This is because setting this.editMode to true does not update the DOM instantaneously.
You should be running your selector asynchronously, so that Polymer has some time to update the DOM, such as:
this.async(function() {
this.$$('#input').focus();
})
Fiddle here.

Computed Binding with Polymer

This is an excerpt of my codes:
<template is="dom-bind">
<iron-ajax auto
url="####"
params=""
handle-as="json"
last-response="{{ajaxResponse}}"></iron-ajax>
<template is="dom-repeat" items="[[ajaxResponse.Items]]">
<div>
[[_formatDate(item.ID.N)]]
</div>
</template>
</template>
...
<script>
Polymer({
is: 'home-view',
_formatDate: function(ID) {
console.log("TEST");
return "TEST";
}
});
</script>
I am getting this Console Warning:
[Warning] [dom-bind::_annotatedComputationEffect]: – "compute method `_formatDate` not defined" (data:text/javascript;charset=utf-8,(fu…%0A, line 265, x10)
So it seems that I do not know how to define _formatDate correctly so that it is recognized by Polymer. Can someone please help?
It looks like you're correctly declaring and using _formatDate().
The warning comes from dom-bind, which is intended only for bindings in index.html, not inside dom-module. You should remove the is="dom-bind" from your top template.
<head>
<base href="https://polygit.org/polymer+1.6.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<home-view></home-view>
<dom-module id="home-view">
<template>
<template is="dom-repeat" items="[[items]]">
<div>[[_formatDate(item)]]</div>
</template>
</template>
<script>
// For cross-browser compatibility, HTMLImports.whenReady()
// needed in index.html only
HTMLImports.whenReady(function() {
Polymer({
is: 'home-view',
properties: {
items: {
type: Array,
value: function() { return ['hello', 'world']; }
}
},
_formatDate: function(id) {
console.log('id', id);
return id;
}
});
});
</script>
</dom-module>
</body>

How to implement html chart in vaadin?

I have used this code in vaadin html file. But output is nothing.
Code refrence: https://vaadin.com/charts-for-polymer
Please let me know how to correct and implement in my vaadin design.
<!DOCTYPE html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/0.7.21/webcomponents-lite.min.js"></script>
<link rel="import" href="https://cdn.vaadin.com/vaadin-charts/3.0.0-alpha9/vaadin-
charts.html">
</head>
<body>
<template is="dom-bind" id="app">
<vaadin-pie-chart id="pie-with-legend">
<title>Revenue by industry</title>
<subtitle>2015</subtitle>
<tooltip point-format="<b>{point.percentage:.1f}%</b>">
</tooltip>
<plot-options>
<pie allow-point-select="true" show-in-legend="true"cursor="pointer">
<data-labels enabled="true"format="{point.name}: {point.y:.1f} M€"></data-labels>
</pie>
</plot-options>
<data-series name="Revenue" data="[[seriesData]]"></data-series>
</vaadin-pie-chart>
<my-data-source data="{{seriesData}}"></my-data-source>
</template>
<dom-module id="my-data-source">
<script>
Polymer({
is: "my-data-source",
properties: {
data: {
type: Array,
notify: true,
value: [
["Aerospace", 53.0],
["Medical", 53.6],
["Agriculture", 25.6],
["Automotive", 17.0],
["Consumers", 12.4],
["Subsidies", 1.4]]
}
}});
</script>
</dom-module>
</body>
</html>
Your code works perfectly in chrome, yet it fails on firefox
(console: Polymer not defined).
What you need to do is, wrap the polymer code in a check like:
addEventListener('WebComponentsReady', function() {
Polymer({
is: "my-data-source",
....
see working example here: https://jsbin.com/tifafepefi/edit?html,output

iron-media-query doesn't work - Polymer 1.0

I'm new to Polymer (1.0).
My <iron-media-query> element is not working. No errors in the console but it does not display anything.
Some improvements would be awesome! I'm trying to get it up and running since 2 hours. :)
Thanks in advance
Ron
<!-- Works correctly -->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-media-query/iron-media-query.html">
<dom-module id="custom-element">
<style>
// Styles here
</style>
<template>
<iron-media-query query="{{query}}" queryMatches="{{smallScreen}}"></iron-media-query>
<template if="{{smallScreen}}">
<strong>Small Screen</strong>
</template>
<template if="{{!smallScreen}}">
<strong>Big Screen</strong>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'custom-element',
properties: {
query: {
type: String,
notify: true
}
}
});
</script>
<custom-element query="(max-width:400px)"></custom-element>
You have to change queryMatches="{{}}" to query-matches="{{}}".
Since you also asked about optmizations:
Since you don't have a massive difference in the data between SmallScreen and not, so:
<strong>[[screenType]] Screen</strong>
<script>
Polymer({
is: 'custom-element',
properties: {
query: {
type: String,
notify: true
},
screenType: {type: String, computed: '_computeScreenType(smallScreen)'}
},
_computeScreenType: (t)=>{return t?"Small":"Big"}
});
</script>