Computed property with firebase element in polymer 1.0 - polymer

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

Related

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 pass data from host element to child element

Having trouble getting my data to work across elements. Say I have an object "records" in my host element. It is usable in that element no problem. But when I try to spin off the view into a separate element, it no longer works.
Here's an example snippet of code. The .template part works fine but I'm not able to replicate the functionality in the child element .my-list. When I try, nothing happens.
<dom-module id="host-element">
...
<template is="dom-repeat" items="{{records}}">
<p>{{item.userName}} - {{item.number}}</p>
</template>
<my-list></my-list>
<script>
Polymer({
is: 'host-element',
ready: function() {
this.records = [
{userName: 'Bob'},
{userName: 'Sally'}
];
}
});
</script>
</dom-module>
If I try simply taking the current .template code and placing it into .my-list, it doesn't work.
I assume I need someway to bind the data into the child element, but I'm not able to figure this out. Adding a: record="{{records}}" to the tag, and then using that in the child element didn't work.
Imagine this is pretty simple, just can't find the answer in the documentation.
It's important that each element's top-level template is a plain template (not is="dom-repeat" or other specialization), otherwise, it should be straightforward:
<link rel="import" href="//polygit.org/components/polymer/polymer.html">
<i>(Requires Chrome)</i>
<host-element></host-element>
<dom-module id="my-list">
<template>
<template is="dom-repeat" items="{{records}}">
<p>{{item.userName}} - {{item.number}}</p>
</template>
</template>
<script>
Polymer({
is: 'my-list'
});
</script>
</dom-module>
<dom-module id="host-element">
<template>
<my-list records="{{records}}"></my-list>
</template>
<script>
Polymer({
is: 'host-element',
ready: function() {
this.records = [{userName: 'Bob'}, {userName: 'Sally'}];
}
});
</script>
</dom-module>

Polymer iron-list dynamically adding items?

I'm trying to migrate some code from Polymer 0.5 to 1.x, this means moving from core-list to iron-list. However, I can not figure out an iron equivalent to how I was adding items to the core-list.
<core-list height="85">
<template>
<div class="{{ {selected: selected} | tokenList }}" style="padding:5px;"><paper-fab mini icon="arrow-forward" title="arrow-forward"></paper-fab> <!--{{index}}-->{{model.name}}</div>
</template>
</core-list>
which is called updated via...
document.querySelector('core-list').data = $.parseJSON('[{"name":"One"},{"name":"Two"}]');
Anyone have any suggestions?
Update : Jul-23-2015 12:20PM PST
#Zikes
Following the suggestion posted, I have the following.
<dom-module id="my-element">
<template>
<iron-list items="[[myItems]]" as="item">
<template>
<div>[[item.name]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'my-element',
properties: {
myItems: Array
},
addItem: function(item) {
this.push('myItems', {name: item});
}
});
</script>
</dom-module>
If this is setup right, how would I go about calling the addItem method from elsewhere?
Update : Jul-23-2015 1:58PM PST
#Zikes
Following is my current code. While I can manipulate the array, values added to it in the ready or addItem method are not being displayed.
<dom-module id="fnord-element">
<template>
<iron-list items="[[myItems]]" as="item">
<template>
<div class="item">[[item.name]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'fnord-element',
properties: {
myItems: {
type: Array,
notify: true
}
},
addItem: function(item) {
//this.push("myItems", {"name":item});
this.myItems=[{name:item}];
alert(this.myItems[0].name);
//alert(item);
},
ready: function() {
//alert('fnord');
this.myItems=[{name:"One"},{name:"Two"}];
}
});
</script>
</dom-module>
<fnord-element id="fnord"></fnord-element>
<paper-button raised onclick="document.querySelector('#fnord').addItem('John Doe');">Test</paper-button>
iron-list uses the items property to generate its items, similar to dom-repeat. What you can do is simply bind it to an Array in your component, like so:
<dom-module id="my-element>
<template>
<iron-list items="[[myItems]]">
<template>
<div>[[item]]</div>
</template>
</iron-list>
</template>
<script>
Polymer({
is:'my-element',
properties: {
myItems: Array
}
});
</script>
</dom-module>
Then, just follow the rules for modifying an Array property and you're all set!

How to global firebase polymer data binding?

I want to use <firebase-login> user object to check if user logged in for my elements. How do I global the user object without calling below code in every custom element?
<firebase-login id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}"></firebase-login>
Create a custum-element that looks something like this,
<polymer-element name="example" attributes="user">
<template>
<firebase-login
id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}">
</firebase-login>
</template>
<script>
Polymer({
})
</script>
</polymer-element>
Then use pvc-globals or create another custom element that passes globals Polymer has an example app-globals where they show how to do this.
<polymer-element name="app-example" attributes="globals">
<template>
<pvc-globals value="{{globals}}"></pvc-globals>
<example-element user="{{user}}"></example-element>
</template>
<script>
Polymer({
ready: function () {
this.globals.user = this.user;
}
});
</script>
</polymer-element>
Or from within the example element:
<polymer-element name="example" attributes="user globals">
<template>
<pvc-globals value="{{globals}}"></pvc-globals>
<firebase-login
id="login"
user="{{user}}"
statusKnown="{{statusKnown}}"
location="FIREBASE_URL"
provider="{{provider}}"
on-error="{{error}}">
</firebase-login>
</template>
<script>
Polymer({
ready: function () {
this.globals.user = this.user;
}
})
</script>
</polymer-element>
Hope this helps!

Polymer: How to loop and render HTML to screen

I am working on a widget that pulls third party information from a database using json. Once the information has been collected, I plan to loop through the information and create the required HTML code and insert this into the template via a {{variable}}
Now I am getting an unexpected result. When I do this, the html is being displayed as text.
Here is some sudo code of the issue:
<polymer-element name="loop-element">
<template>
{{customerList}}
</template>
<script>
Polymer('loop-element', {
ready: function() {
this.loadCustomerList();
}
customerList:"Loading customer list...",
loadCustomerList: function() {
CustomerNameArray[] = //Get the array from jSon file
i = 0;
do {
this.customerList = "<div>" + customerNameArray[i] + "</div>";
} while (customerNameArray[i]);
}
});
</script>
</polymer-element>
Essentially the DIV's are not being rendered, instead they are being printed to the screen as text:
"<div>Name 1</div>" "<div>Name 2</div>" ... n
Instead of:
Name 1
Name 2
Name n...
You can see a JSBin example here: http://jsbin.com/tituzibu/1/edit
Can anyone recommend how to go about outputting a list to the template?
Polymer v.1.0
/* relative path to polymer.html*/
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="employee-list">
<style>
/* CSS rules for your element */
</style>
<template>
<div> Employee list: </div>
<template is="dom-repeat" items="{{employees}}">
<div>First name: <span>{{item.first}}</span></div>
<div>Last name: <span>{{item.last}}</span></div>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'employee-list',
ready: function() {
this.employees = [
{first: 'Bob', last: 'Smith'},
{first: 'Sally', last: 'Johnson'}
];
}
});
</script>
doc
You should use Polymer's DOM-based data-binding features rather than creating the markup yourself.
<template repeat="{{customer, i in customers}}">
<div>{{i}}, {{customer.name}}</div>
</template>
http://www.polymer-project.org/docs/polymer/databinding.html#an-example
Maybe a little late...
If you want to stick to your approach you could use this.injectBoundHTML:
<polymer-element name="loop-element">
<template>
<div id='customerList'> </div>
</template>
<script>
Polymer('loop-element', {
ready: function() {
this.loadCustomerList();
}
customerList:"Loading customer list...",
loadCustomerList: function() {
CustomerNameArray[] = //Get the array from jSon file
i = 0;
do {
this.customerList = "<div>" + customerNameArray[i] + "</div>";
} while (customerNameArray[i]);
this.injectBoundHTML( this.customerList,
this.$.customerList);
}
});
</script>
</polymer-element>
However the first approach is better..
In Polymer 3.0 you can do the following:
<dom-repeat items="{{customers}}">
<template>
{{item.name}}
</template>
</dom-repeat>
Any list is binded to the items property of dom-repeat, and item within the template is used to represent the object from the list. You can read more about the dom-repeat on the Polymer 3.0 API reference page here.