Computed Binding with Polymer - 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>

Related

Subset hyphenated JSON element in Polymer data binding

Consider the following JSON:
{"EMD-4091":["EMD-4084","EMD-4090"]}
which is the result of a fictitious iron-ajax call as follows:
<iron-ajax
auto
url="http://me.com/get/EMD-4091"
handle-as="json"
last-response="{{my_data}}">
</iron-ajax>
Suppose I need to refer to the inner array, say, in a dom-repeat: how would I refer to 'EMD-4091' in a data binding? e.g.
<template is="dom-repeat" items="{{my_data????}}> <!-- what should this be?-->
<p>{{item}}</p>
</template>
If the data wasn't hyphenated this is a trivial task. The hyphen is the challenge I'm facing.
P
The data binding can still parse the hyphenated key without a problem, so your binding would be:
items="{{my_data.EMD-4091}}"
HTMLImports.whenReady(() => {
"use strict";
Polymer({
is: 'x-foo',
properties : {
my_data: {
type: Array,
value: () => ({"EMD-4091":["EMD-4084","EMD-4090"]})
}
}
});
});
<head>
<base href="https://polygit.org/polymer+1.7.0/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<template is="dom-repeat" items="[[my_data.EMD-4091]]">
<div>[[item]]</div>
</template>
</template>
</dom-module>
</body>
codepen

Polymer: Passing properties to child element doesn't work

I'm trying to output data from a custom Polymer component <data-component> in an <iron-list> but nothing is shown when I open the page. It works when I pass an array of objects directly to the iron-list like <iron-list items='[{"name": "test1"}, {"name":"test2"}]' >
What am I doing wrong here and is the <template is="dom-bind" id="t"> mandatory?
index.html
<html>
<head>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../data-component.html">
<link rel="import" href="../../iron-list/iron-list.html">
</head>
<body unresolved>
<template is="dom-bind" id="t">
<data-component>
<!--<iron-list items='[{"name": "test1"}, {"name":"test2"}]' > WORKS -->
<iron-list items="{{data}}" >
<template>
<div>
Name: <span>{{item.name}}</span>
</div>
</template>
</iron-list>
</data-component>
</template>
</body>
</html>
data-component.html
<link rel="import" href="../polymer/polymer.html">
<dom-module id="data-component">
<template>
<content></content>
</template>
</dom-module>
<script>
window.coolData = [
{"name": "Bob"},
{"name": "Tim"},
{"name": "Mike"}
];
Polymer({
is: 'data-component',
properties: {
data: {
value: window.coolData
}
}
});
</script>
I'm going to suggest an alternative answer to what I have already posted. If you want your data-component to always contain the iron-list then you can use this version here. However, if the content of the data-component should be more flexible use my other answer.
If you move the iron-list inside the data-component you can remove the dom-bind in your index.html.
data-component.html
<link rel="import" href="../polymer/polymer.html">
<dom-module id="data-component">
<template>
<iron-list items="{{data}}" >
<template>
<div>
Name: <span>{{item.name}}</span>
</div>
</template>
</iron-list>
</template>
</dom-module>
<script>
window.coolData = [
{"name": "Bob"},
{"name": "Tim"},
{"name": "Mike"}
];
Polymer({
is: 'data-component',
properties: {
data: {
type: Array,
value: window.coolData
}
}
});
</script>
index.html
<body unresolved>
<data-component></data-component>
</body>
You also have to add a data-binding to your data-component. Otherwise, the system does not know that data (in your iron-list) should refer to the data property in your custom element.
<data-component data="{{data}}">
<iron-list items="{{data}}" >
...
</iron-list>
</data-component>
The dom-bind is necessary if you want to have data-binding outside of a Polymer element, which seems to be the case here.
You should also make sure that the data property is configured to notify changes and that its type is set to Array.
Polymer({
is: 'data-component',
properties: {
data: {
type: Array,
value: window.coolData,
notify: true
}
}
});

Polymer 1.0 deep path array binding

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>

Computed property with firebase element in polymer 1.0

I have an element where I receive some data from firebase which looks like that:
<dom-module id="my-positions-list">
<template is="dom-bind">
<firebase-collection data="{{aa}}"
location="https://myapp.firebaseio.com/positions">
</firebase-collection>
<template is="dom-repeat" items="[[aa]]" as="item">
<p><span>{{url}}</span></p>
</template>
</template>
<script>
(function () {
Polymer({
is: 'my-positions-list',
properties: {
url:{
type:String,
computed: 'url(this.item.title)'
}
},
url: function(title) {
return "/positions/" + title;
}
});
})();
</script>
</dom-module>
I am trying to create a computed property "url" using the title attribute of the "item" but had no luck, any idea how to achieve that?
I also get this weird message in my console from the polymer-mini.html file:
[my-positions-list::_prepTemplate]: top-level Polymer template must not be a type-extension, found template Move inside simple .
Any idea how to fix it?
Try this:
<dom-module id="my-positions-list">
<template is="dom-bind">
<firebase-collection data="{{aa}}"
location="https://myapp.firebaseio.com/positions/"></firebase-collection>
<template is="dom-repeat" items="[[aa]]">
<p><span>{{url(item.title)}}</span></p>
</template>
</template>
</dom-module>
<script>
(function () {
Polymer({
is: 'my-positions-list',
url: function(title) {
return "/positions/" + title;
}
});
})();
</script>
here the it in jsbin http://jsbin.com/lokegu/edit?html,output

Alternative to "in" expression for iterating over objects polymer (0.5.4)

Using the repeat and in expression it is trivial to iterate over arrays, but swapping
this.data = ["foo","bar"];
to
this.data = {foo:"football",bar:"barfly"}
fails to iterate over the object. I have seen examples of using Object.key in order to get each value, but the index returned is 0,1 instead of "foo" "bar".
While this simple example doesn't use 2 way binding, I would like to keep support for it, in case I need it in the future.
http://jsbin.com/copogeyome/1/
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Polymer</title>
<script src="http://www.polymer-project.org/components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
</head>
<body>
<polymer-element name="an-consumer" attributes="data" noscript>
<template>testing {{data.foo}}<br>
<template id="foo">f {{}}<br></template>
<template id="bar">b {{}}<br></template>
<template id="0">0 {{}}<br></template>
<template id="1">1 {{}}<br></template>
<template id="2">2 {{}}<br></template>
{
<template repeat="{{obj,index in data}}" bind="{{data}}">
( {{index}} - {{obj}} ) = <template ref="{{index}}" bind="{{obj}}"></template>
</template>
}
</template>
</polymer-element>
<polymer-element name="an-supplier" attributes="data">
<template></template>
<script>
Polymer({
ready: function(){
this.data = ["foo","bar"];
//this.data = {foo:"football",bar:"barfly"}
}
});
</script>
</polymer-element>
<polymer-element name = "an-root" noscript>
<template>
<an-supplier data="{{stuff}}"></an-supplier>
<an-consumer data="{{stuff}}"></an-consumer>
</template>
</polymer-element>
<an-root>
</an-root>
</body>
</html>
While there is [yet] no built-in ability to iterate over object, you might easily achieve this functionality with filter:
<template repeat="{{key in data | getKeys}}">
<span>Key: {{key}}</span>
<span>Value: {{data[key]}}</span>
</template>
<script>
Polymer({
ready: function(){
// this.data = ["foo","bar"];
this.data = {foo:"football",bar:"barfly"}
}
// filter function to use in looping objects
getKeys : function(o) {
return Object.keys(o);
}
});
</script>
Whether you have additional questions, please, don’t hesitate to ask.
Live: http://jsbin.com/munehitogu/1/edit