error displaying core-ajax custom element - polymer

i am making a custom element to display a wall of album covers from a subsonic server. when declared the element will query the server and get back 200 response. the response logs in the console correctly. but nothing is rendered in the browser.
<link rel="import" href="../bower_components/core-ajax/core-ajax.html">
<link rel="import" href="album-info-big-art.html">
<polymer-element name="albums-wall" attributes="url">
<template>
<core-ajax auto url="{{url}}" handleAs="json" response="{{response}}"></core-ajax>
<template id='albums' repeat="{{response.subsonic-response.albumList2.album}}">
<album-info-big-art artist='{{artist}}' title='{{name}}' img='{{coverArt}}'></album-info-big-art>
</template>
</template>
<script>
Polymer('albums-wall',{
responseChanged: function(e) {
var albums = this.response;
console.log(albums);
}
});
</script>
</polymer-element>
the response looks like.
Object {subsonic-response: Object}
subsonic-response: Object
albumList2: Object
album: Array[60]
__proto__: Object
status: "ok"
version: "1.10.2"
xmlns: "http://subsonic.org/restapi"
__proto__: Object
__proto__: Object
i am pretty sure i have missed something in the js section.

The problem is the property name subsonic-response. You cannot use a dash in a path property name. Rewrite your expression to use array syntax: response['subsonic-response']....

Related

Handling of loading indicator for multiple ajax calls in Polymer

I'm using Polymer 1.0 to create a web application.
I have various elements doing one or more iron-ajax calls and I have another element for showing the loading-overlay. But in my current sollution I have added the loading-overlay, with its logic to show or not, to every element doing ajax calls.
<dom-module id="backend-call-application">
<template>
<iron-ajax id='loadA' loading="{{_loadingA}}" ...></iron-ajax>
<iron-ajax id='loadB' loading="{{_loadingB}}" ...></iron-ajax>
<loading-overlay id="loadingOverlay" with-backdrop></loading-overlay>
</template>
<script>
Polymer({
is: 'backend-call-application',
observers:[
"_isXhrLoading(_loadingA,_loadingB,....)"
],
_isXhrLoading: function() {
for (var i = 0; i < arguments.length; i++) {
if (arguments[i]) {
this.$.loadingOverlay.open()
return;
}
}
this.$.loadingOverlay.close()
}
});
</script>
</dom-module>
Now my question is, what is the best way to show such a loading-overlay?
One idea of mine would be, to have something like an observer in the loading overlay. So every element doing requests will bind its properties to the observer. These properties could be stored in an array and everytime on change, the loading-overlay checks if at least one have loading properties set to true. When one or more properties are true the loading-overlay will be opened and when all requests finished loading it will be closed.
Another idea was to use events to tell the loading-overlay when a element starts/stops loading. But here will be the problem, that I have more than one request at the same time (The first request closes the overlay, but the page hasn't finished loading).
Edit:
The loading-overlay is an element containing the IronOverlayBehavior.
<link rel="import" href="../../../bower_components/polymer/polymer.html">
<link rel="import" href="../../../bower_components/iron-overlay-behavior/iron-overlay-behavior.html">
<link rel="import" href="../../../bower_components/paper-spinner/paper-spinner.html">
<dom-module id="loading-overlay">
<template>
<paper-spinner active="true"></paper-spinner>
</template>
<script>
Polymer({
is: 'loading-overlay',
behaviors: [
Polymer.IronOverlayBehavior
]
});
</script>
</dom-module>
use one property for loading instead of 2!!
<iron-ajax id='loadA' loading="{{_loading}}" ...></iron-ajax>
<iron-ajax id='loadB' loading="{{_loading}}" ...></iron-ajax>
bind loading value to loading-overlay with some attribute and when loading is true display loader
<loading-overlay id="loadingOverlay" is-loading="[[_loading]]" with-backdrop></loading-overlay>
so each time any ajax is made then _loading will become true so displays loader
I think the only thing you could shorten is the _isXhrLoading observer.
_isXhrLoading: function() {
if(Array.from(arguments).indexOf(true) >= 0) {
this.$.loadingOverlay.open()
} else {
this.$.loadingOverlay.close()
}
}

How to implement custom filters in Polymer 1.7.x

I am trying to implement a custom filter using Polymer v1.7.0 currently. However, it does not work at all; when I try to use a filter the output is just the raw expression, unprocessed.
I have tried it like it's done here: https://github.com/PolymerLabs/polymer-patterns/blob/master/snippets/filters/using-custom-filters.html but using this code:
<div id="toFixed">{{10.123456789 | toFixed(2)}}</div>
only results in
{{10.123456789 | toFixed(2)}} in the resulting document.
Is my linked source outdated? I couldn't find any valuable information in the Polymer docs so a nudge into the right the direction is appreciated.
You don't need pipe in Polymer 1.x to achieve this. You can directly call an function and pass it the value that you want to
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="my-element">
<template>
{{format(myVal)}}
<br>{{format("hello")}}
</template>
</dom-module>
<script>
Polymer({
is: "my-element",
properties: {
myVal: {
type: String,
value: "Hi"
}
},
format: function(input) {
return input + " John";
}
});
</script>
<my-element></my-element>

Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'paper-button'

I'm using polymer 1.2.1
I'm trying to create two polymer elements paper-button & paper-input.
I had imported following in head
<script src="third-party/js/bower/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="third-party/html/bower/polymer/polymer.html">
<link rel="import" href="third-party/html/bower/paper-button/paper-button.html">
<link rel="import" href="third-party/html/bower/paper-input/paper-input.html">
and added following in body
<paper-button>Flat button</paper-button>
<paper-button raised>Raised button</paper-button>
<paper-button noink>No ripple effect</paper-button>
<paper-button toggles>Toggle-able button</paper-button>
<paper-input label="total">
<div prefix>$</div>
<paper-icon-button suffix icon="clear"></paper-icon-button>
</paper-input>
<script>
Polymer({
is: "paper-button",
// add a callback to the element's prototype
created: function() {
console.log("inside pol1");
this.textContent = "I'm a proto-element!"
}
});
Polymer({
is: "paper-input",
// add a callback to the element's prototype
created: function() {
console.log("inside pol2");
this.textContent = "I'm a proto-elemente2!"
}
});
</script>
I'm expecting a change in text of respective elements with some console but none of these happens. I get an error saying
"Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'paper-button'. A type with that name is already registered."
I'm not quite sure what you are trying to achieve, but the answer to your question is this:
Your paper-input and paper-button have already been registered into Polymer by your <link rel="import"> tags in your <head> section, so naturally when you try to re-register them using Polymer({is:"paper-button"...}), it fails...
I also wouldn't recommend overriding a packaged element's created() callback - if you want to do your own custom tasks, create a new custom element that wraps your target element, and then call your new element instead.

How to get totalResults from the youtube response?

It is a very big question, but
Here is my HTML
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/core-ajax/core-ajax.html">
<polymer-element name="test-element" attributes="q">
<template>
<core-ajax auto url="https://www.googleapis.com/youtube/v3/search"
params='{"part":"snippet", "q":"{{qry}}", "maxResults":"{{vidMaxResults}}",
"key":"{{key}}"}' handleAs="json" response="{{response}}" method='GET'></core-ajax>
<template repeat="{{item in response.items}}">
<div>
<p>{{item.snippet.title}}</p>
</div>
</template>
<template bind>
<span>Total results: {{item.totalResults}}</span>
</template>
</template>
<script>
Polymer({
response: null,
vidMaxResults: 10,
qry: 'Hello',
key: ''
});
</script>
</polymer-element>
How do i get the totalResults from the json response??
How do i get manage all the data if maxResults is not given as parameter (like thousands of results, but i would like to view only 10 at a time)?
Also how do i get a link of the video itself for every video results (not the youtube link)??
I am new to using these polymer and youtube api so please give me some basic idea too.
Thanks in advance :)
The response from a youtube.search.list() call looks like:
{
"pageInfo": {
"totalResults": 1000000
},
"items": [{...}, {...}]
}
(with some fields cut for brevity).
You can access the total results value as response.pageInfo.totalResults.
There are no links to the raw video bytes exposed in the YouTube Data API responses. You should use the video ids to either link to the YouTube player pages or use something like <google-youtube> to embed the player on your page.

Polymer: how to parse the index to the elements using template repeat

I've been trying to use Polymer for a project I'm working on. And although I enjoyed it quite a lot so far, I ran into a problem I just can't solve.
I dumped it down to a simple example. Basically it's just a list element (item-list) that contains item elements (item-card) and i want to parse the items position to the element via the attribute pos. But for some reason the items attribute is allways undefined! Is this because the attribute is bound to the variable i, which dies after the template repeat? If so, how do I work around it? Is there a different approach I should be using here?
SOLUTION: You can find the solution by reading through all the comments, but to sum it up: apperantly there was a timing issue and the attribute wasn't ready at the ready callback. But I found out about the domReady callback (polymer lifecycle documentation). Using domReady it works just fine! Thanks to Günter Zöchbauer for the help!
This is the item-list.html:
<link rel="import" href="components/polymer/polymer.html">
<link rel="import" href="item-card.html">
<polymer-element name="item-list">
<template>
<style>
</style>
<template repeat="{{values, i in data.data}}">
<item-card pos="{{i}}"></item-card>
</template>
</template>
<script>
Polymer({
created: function()
{
this.num = 123456;
this.data = { "data":
[
{
"value":999
},
{
"value":666
},
{
"value":555
},
{
"value":222
}
]
};
}
});
</script>
</polymer-element>
This is the item-card.html
<link rel="import" href="components/polymer/polymer.html">
<polymer-element name="item-card" attributes="pos">
<template>
<style>
</style>
</template>
<script>
Polymer({
ready: function()
{
console.log("ready: " + this.pos);
}
});
</script>
</polymer-element>
I didn't bother putting the index.html in, since it just containts one item-list element.
Thanks alot!!
I think you need a pos field in <item-card> in addition to the attributes="pos" declaration.
The repeated element also references the bound model which can be accessed like querySelector('item-card').templateInstance.model property.
See https://github.com/PolymerLabs/polymer-selector/blob/master/polymer-selector.html#L286 for an example.
Info:
According to the comments it turned out to be a timing issue. The value wasn't yet assigned when the ready callback was called but using domReady worked.