Polymer 2.0 - How do I use iron-ajax? - polymer

I am trying to bind local properties.json and trying to create dynamic elements, but the problem is I am not getting any console errors and not seeing JSON in the UI.
I didn't find a Polymer 2.0 example for using <iron-ajax>, but I found ones for Polymer 1.0 only.
Here's the code I've tried:
polymer-input.html
<link rel="import" href="https://www.polymer-project.org/0.5/components/polymer/polymer-element.html">
<link rel="import" href="https://www.polymer-project.org/0.5/components/iron-ajax/iron-ajax.html">
<dom-module id="polymer-app">
<template>
<style>
:host {
display: block;
}
</style>
<iron-ajax auto="" url="properties.json" handle-as="json" last-response="{{ajaxResponse}}"></iron-ajax>
<template is="dom-repeat" items="[[ajaxResponse]]">
<span>[[item.name]]</span>
</template>
<h2>Hello [[prop1]]!..[[ajaxResponse]]</h2>
</template>
<script>
/**
* #customElement
* #polymer
*/
class PolymerApp extends Polymer.Element {
static get is() { return 'polymer-app'; }
static get properties() {
return {
prop1: {
type: String,
value: 'polymer-app'
}
};
}
}
window.customElements.define(PolymerApp.is, PolymerApp);
</script>
</dom-module>
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>polymer</title>
<meta name="description" content="custom ele">
<script src="https://www.polymer-project.org/0.5/components/webcomponentsjs/webcomponents-loader.js"></script>
<link rel="import" href="polymer-app/polymer-app.html">
<link rel="import" href="polymer-input/polymer-input.html">
</head>
<body>
<polymer-app></polymer-app>
</body>
</html>
properties.json:
{
{
name:"Name",
type:"string",
size:20
},
{
name:"Age",
type:"number",
size:20
}
}
I am getting below output instead of properties json data

The first problem is your demo uses a base URL for Polymer 0.5, while your code is using Polymer 2.0 syntax.
That is, this code:
<link rel="import" href="https://www.polymer-project.org/0.5/components/polymer/polymer-element.html">
<link rel="import" href="https://www.polymer-project.org/0.5/components/iron-ajax/iron-ajax.html">
...should be something like this:
<link rel="import" href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/polymer/polymer-element.html">
<link rel="import" href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/iron-ajax/iron-ajax.html">
Second, your properties.json file contains invalid JSON. It looks like you meant to use square brackets for array data; and your keys are missing quotes. You'll notice that running the file contents through JSON.parse() would throw an error.
This text:
{
{
name:"Name",
type:"string",
size:20
},
{
name:"Age",
type:"number",
size:20
}
}
...should be something like this:
[
{
"name":"Name",
"type":"string",
"size":20
},
{
"name":"Age",
"type":"number",
"size":20
}
]
Third, note that <iron-ajax> automatically sets <iron-ajax>.lastResponse to null if <iron-ajax>.handleAs is json and the response cannot be parsed as JSON. In your case, the invalid JSON in properties.json would cause lastResponse to be set to null, preventing your example from rendering the intended fields.
Here's a working Polymer 2 <iron-ajax> demo (using your example code) with all corrections made:
http://plnkr.co/edit/2mpJd1b0UF5FqAr2BOxL?p=preview

Related

Polymer 2.0 - Trying to create HTML template from JSON with events

I am trying to create HTML templates from JSON object and able to render elements but the events are not getting added to the element and not showing up in the developer tools/Shadow DOM.
Codepen for reference - https://codepen.io/nagasai/pen/bRjWbd
Issue: Events - onkeypress, onkeyup,onchange are not showing on input and checkbox elements and couldn't add them but other options are showing up like name, type(Again type is getting displayed only for checkbox but not for textbox)
Screenshot for actual issue
HTML:
<head>
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-collapse/iron-collapse.html">
</head>
<body>
<x-foo attr='[{
"type":"text",
"title":"Textbox Name",
"name":"temp",
"requried":"requried",
"onkeypress":"testKeyPress()",
"onkeyup":"testKeyUp()",
"onchange":""
},{
"type":"checkbox",
"title":"CheckBox Name",
"name":"temp",
"requried":"requried",
"disabled":"disabled",
"onkeypress":"",
"onkeyup":"",
"onchange":"testChange()"
}]'></x-foo>
<dom-module id="x-foo">
<template>
<template is="dom-repeat" items="{{attr}}">
<label>{{item.title}}</label>
<input type="{{item.type}}"
required="{{item.required}}"
name="{{item.name}}"
onchange="{{item.onchange}}"
onkeypress="{{item.onkeypress}}"
onkeyup="{{item.onkeyup}}()"
>
</template>
</template>
</dom-module>
</body>
JS:
class XFoo extends Polymer.Element {
static get is() { return 'x-foo'; }
static get properties() {
return {
attr:{
type:Array
}
};
}
}
customElements.define(XFoo.is, XFoo);
Correct me if I'm wrong but it should be:
on-change="{{item.onchange}}"
on-keypress="{{item.onkeypress}}"
on-keyup="{{item.onkeyup}}()"
Reference: https://www.polymer-project.org/2.0/docs/devguide/gesture-events

app-location deletes query string parameters

I have a very simple polymer 2 app, which uses query query string parameters. Moving to Polymer 2.0.1 and app-location 2.0 (instead of rc and preview versions), I noticed that simply having an app-location element deletes all query string parameters from the url.
Try this url: https://api-1913.s3-eu-west-1.amazonaws.com/index.html?foo=bar, and notice how the query string is removed during loading.
Here's all the code:
index.html:
<!DOCTYPE HTML>
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<link rel="import" href="/my-app.html">
<html>
<head>
</head>
<body>
<my-app></my-app>
</body>
</html>
my-app.html:
<link rel="import" href="/bower_components/polymer/polymer.html">
<link rel="import" href="/bower_components/app-route/app-location.html">
<dom-module id="my-app">
<template>
<app-location></app-location>
<h1>Coin</h1>
</template>
<script>
class App extends Polymer.Element{
static get is(){return 'my-app'}
ready(){
super.ready()
console.log('ready')
}
}
customElements.define(App.is, App)
</script>
</dom-module>
Specifying query-params attribute to map it to a property of App does not change anything. Remove the app-location element and query string is kept.
Has anyone seen this behavior? Is there any workaround - except a rollback to a previous version?
It is a bug. You can temporarly remove the default value in iron-location element until the fix is released.
Lines to remove
value: function() {
return {};
}
Affected property
paramsObject: {
type: Object,
notify: true,
value: function() {
return {};
}
},
Reference:
https://github.com/PolymerElements/iron-location/pull/86/commits/3732e93ce2197178f76c3c2073438b9cd15096b4

Polymer: Whats the difference between computed property and function like {{some(prop1)}}

Whats the difference between defining a computed property and using it like {{prop}}
prop: {
type: String,
computed: 'some(prop1)'
}
vs a function binding like
{{some(prop1)}}
The property is, as the name implies, also a property of the node object. It can notify outside listeners or reflect to attribute.
Function binding is only used to that. You can call it from the outside but it should have no effect - assuming that the function has no side-effects which is shouldn't.
The most important difference however, is that compute function will evaluate for each binding usage. Computed property will evaluate only once when a dependency changes. See below what happens in the console whenever you click INCREMENT.
Polymer({
is: 'my-elem',
properties: {
i: {
type: Number,
value: 0
},
c: {
computed: 'compute(i)'
}
},
inc: function() {
console.clear();
this.i += 1;
},
compute: function(i) {
console.log('computing property binding');
return i * 2;
},
f: function(i) {
console.log('computing function binding');
return i * 2;
}
});
<!DOCTYPE html>
<html>
<head>
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import"/>
<link href="paper-button/paper-button.html" rel="import" />
</head>
<body>
<my-elem></my-elem>
<dom-module id="my-elem">
<template>
<div>Computed: [[c]]</div>
<div>Computed: [[c]]</div>
<div>Computed: [[c]]</div>
<div>Computed: [[c]]</div>
<div>Function: [[f(i)]]</div>
<div>Function: [[f(i)]]</div>
<div>Function: [[f(i)]]</div>
<div>Function: [[f(i)]]</div>
<paper-button on-tap="inc">Increment</paper-button>
</template>
</dom-module>
</body>
</html>

Extending dart:html class "ButtonElement" in Dart

I tried to extend a <button>, but so far did not succeed.
What am I doing wrong. I'm using the Dart Editor+SDK 1.5.2
In pubspec.yaml the version for Polymer is set to:
polymer: ">=0.11.0 <0.12.0"
index.html
<!DOCTYPE html>
<html>
<head>
<!-- <script src="packages/web_components/platform.js"></script>
not necessary anymore with Polymer >= 0.14.0 -->
<script src="packages/web_components/dart_support.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Extended Button - Dart v1.5.2</title>
<!--Extended Button-->
<link rel="import" href="view/ext_button.html" />
</head>
<body>
<button is="ext-button">Test Button</button>
<script type="application/dart">export "package:polymer/init.dart";</script>
</body>
</html>
view/ext_button.dart
import "dart:html";
import "package:polymer/polymer.dart";
#CustomTag("ext-button")
class ExtButton extends ButtonElement {
ExtButton.created() : super.created();
factory ExtButton(){
onClick.listen(clicked);
}
void clicked(MouseEvent e){
print("Ext-Button clicked");
}
}
view/ext_button.html
<!DOCTYPE html>
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="ext-button" extends="button">
<template>
</template>
<script type="application/dart" src="ext_button.dart"></script>
</polymer-element>
So the code above does not work, but as soon as write it like below (just to validate the ext-button works) it tells me the following:
"web/index.html:20:7: custom element "ext-button" extends from "button", but this tag will not include the default properties of "button".
To fix this, either write this tag as <button is="ext-button"> or remove the "extends" attribute from the custom element declaration."
<ext-button>Test Button</ext-button>
So a little bit confused ;-) I think the fix is easy and simple - but I just don't see the problem ;-(
Just for further references, the two things above solved the problem.
Here are the updated parts, now it works.
view/ext_button.dart
import "dart:html";
import "package:polymer/polymer.dart";
#CustomTag("ext-button")
class ExtButton extends ButtonElement with Polymer {
ExtButton.created() : super.created()
{
polymerCreated();
onClick.listen(clicked);
}
void clicked(MouseEvent e){
print("Ext-Button clicked");
}
}
view/ext_button.html
<!DOCTYPE html>
<link rel="import" href="packages/polymer/polymer.html">
<polymer-element name="ext-button" extends="button">
<template>
<content></content>
</template>
<script type="application/dart" src="ext_button.dart"></script>
</polymer-element>
As far as I see, you are missing thwo things:
a call to polymerCreated() inside the custom elements constructor.
and extends ButtonElement with Polymer
There are already similar question. I'll look them up later when I have more time. Maybe you find them yourself in the meantime. Please add a comment with a link if you do.

Understanding the constructor attribute in Polymer elements

A Polymer noob...
I'm trying to create a custom element as per the Polymer API docs, where my main page looks like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Polymer</title>
<script src="bower_components/platform/platform.js"></script>
<link rel="import" href="bower_components/polymer/polymer.html">
</head>
<body>
<div id="test"></div>
<polymer-element name="book-template" constructor="BookTemplate" noscript>
<template>
<style>
h1 { color: orange; }
</style>
<h1>Hello from some-foo</h1>
</template>
</polymer-element>
</body>
</html>
I know that the page content will render if I just put <book-template></book-template> on the page, or if I do something like this inside the <body> tag:
<script>
var book = document.createElement('book-template');
document.getElementById('test').appendChild(book);
</script>
But I'm trying to utilize the element's constructor attribute, assuming that this will create the element when placed somewhere inside of <body>:
<script>
var book = new BookTemplate();
</script>
...but getting a console message that BookTemplate() is not defined.
I'm sure it's something simple...any idea? Thanks in advance.
I guess you have to wait for the polymer-ready event, so that the constructor is available in the global window object http://jsbin.com/kosuf/2/edit?html,console,output:
<script>
document.addEventListener('polymer-ready',function() {
var book = new BookTemplate();
if (book) {
console.log('Ok');
}
});
</script>