reading json and converting to HTML - polymer - polymer

I am trying to read local json file and convert it to HTML layout
I was able to read JSON from local but struggling to read and render on UI
HTML:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/polymer/polymer.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-cdn/1.5.0/lib/iron-ajax/iron-ajax.html">
</head>
<body>
<template is="dom-bind">
<iron-ajax
auto
url="properties.json"
last-response="{{data}}"
handle-as="json">
</iron-ajax>
<div><span>{{data}}</span></div>
<!-- <template is="dom-repeat" items="{{data}}">
<div><span>{{item.name}}</span></div>
</template> -->
</template>
<script>
(function (document) {
'use strict';
var app = document.querySelector('#app');
window.addEventListener('WebComponentsReady', function() {
var ironAjax = document.querySelector('iron-ajax');
ironAjax.addEventListener('response', function() {
console.log(ironAjax.lastResponse);
});
ironAjax.generateRequest();
});
})(document);
</script>
</body>
</html>
properties.json file
{
"main":{
"header":{
"label" :"Employee Template",
"logo":"abc.png"
},
"footer":{
"label" :"2017 All rights reserved.",
"author":"abc"
},
"menu":[
{
"label":"Add",
"url":"/Add"
},
{
"label":"Delete",
"url":"/Delete"
}
]
}
I am trying to render the above json as below HTML
<header><h1>{{Employee.header.label}}</h1>
<img src={{Employee.header.logo}}>
</header>
<ul>
<li>{{Employee.menu[0].label}}</li>
<li>{{Employee.menu[0].label}}</li>
</ul>
<footer><h1>{{Employee.footer.label}}</h1>
<div>{{Employee.footer.author}}></div>
</footer>
I tried iron-ajax for rendering, but it works only on array of objects and not reading through the json and didnt find much information on documentation

At first, you are propably missing main in all bindings? according to your json the hiearchy is main.header.label and not header.label.
Another issue: When you are pointing to some index of array in bindings you are using {{Employee.menu[0].label}} but it should be {{Employee.menu.0.label}}. Remember this, because once you will use array mutation methods, it will be same.
If your JSON's structure is always like that and never changes, then it's super simple and you have already did, what you wanted. If your JSON's structure can change to something more complex, then you will have to propably write your own parser. which means, iterating all keys insinde json, creating elements and putting content in it. It will be a little bit harder, but it is possible.
I don't know how your json can look like so i won't write you parser. You will have to try it on your own.
It will start something like:
for(var key in this.Employee.main) {
var el = document.createElement(key);
...
}

here is an fiddle with an working example of your code: fiddle
The fiddle is ab bit different since i have no clue how to do ajax in fiddle but your code sould look like this:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.rawgit.com/download/polymer-
cdn/1.5.0/lib/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="https://cdn.rawgit.com/download/polymer-
cdn/1.5.0/lib/polymer/polymer.html">
<link rel="import" href="https://cdn.rawgit.com/download/polymer-
cdn/1.5.0/lib/iron-ajax/iron-ajax.html">
</head>
<body>
<template is="dom-bind">
<iron-ajax
auto
url="properties.json"
last-response="{{data}}"
handle-as="json">
</iron-ajax>
<header><h1>{{Employee.header.label}}</h1>
<img src={{Employee.header.logo}}>
</header>
<ul>
<li>{{data.main.menu.0.label}}</li>
<li>{{data.main.menu.0.label}}</li>
</ul>
<footer><h1>{{data.main.footer.label}}</h1>
<div>{{data.main.footer.author}}></div>
</footer>
</template>
<script>
(function (document) {
'use strict';
var app = document.querySelector('#app');
window.addEventListener('WebComponentsReady', function() {
var ironAjax = document.querySelector('iron-ajax');
ironAjax.addEventListener('response', function() {
console.log(ironAjax.lastResponse);
});
ironAjax.generateRequest();
});
})(document);
</script>
</body>
</html>`

Related

How to access innerHTML of a template in the content of an element

First off, I apologize for the title-gore. I struggled to summarize this issue in a single sentence.
I have a Polymer element. In my element, I wish to display (or simply log to console) the innerHTML of a template element that is a child of (contents of) the element instance.
(Please note that the intent here is to create an element similar to the demo-snippet of iron-demo-helpers.)
Consider the following Polymer element:
<link rel="import" href="../../polymer/polymer.html">
<dom-module id="print-contents-html">
<script>
Polymer({
is: 'print-contents-html',
attached: function() {
var template = Polymer.dom(this).queryDistributedElements('template')[0];
console.log(template.innerHTML);
}
});
</script>
</dom-module>
Very simply, I query for the 'template' element and log its inner HTML.
Now consider the following usage:
<!doctype html>
<html>
<head>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="./print-contents-html.html">
</head>
<body>
<print-contents-html>
<template>
Hello World
</template>
</print-contents-html>
</body>
</html>
As expected, this results in "Hello World" being logged to the console.
However, I am trying to make use of the 'print-contents-html' element within another Polymer element:
<link rel="import" href="../../polymer/polymer.html">
<link rel="import" href="./print-contents-html.html">
<dom-module id="simple-demo">
<template>
<print-contents-html>
<template>
Hello World from simple demo
</template>
</print-contents-html>
</template>
<script>
Polymer({
is: 'simple-demo',
});
</script>
</dom-module>
Now if I update the usage to also include an instance of the simple-demo element:
<!doctype html>
<html>
<head>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="./print-contents-html.html">
<link rel="import" href="./simple-demo.html">
</head>
<body>
<print-contents-html>
<template>
Hello World
</template>
</print-contents-html>
<simple-demo></simple-demo>
</body>
</html>
I would expect to see both "Hello World" and "Hello World from simple demo" logged to the console. However the simple demo message is not logged.
It appears that while the queryDistributedElements() does return the instance of the template element, the innerHTML field is an empty string.
Does anyone know why this is the case? That accessing the content/child template element does not have its innerHTML set?
Secondly, does anyone know of an alternative method through which I can access the innerHTML of the template element that is a content/child of a polymer element?
Kind Regards,
Andrew Butler
This issue is discussed in Polymer's Github repository.
The solution is to add a preserve-content attribute it the inner <template> tag:
<dom-module id="simple-demo">
<template>
<print-contents-html>
<template preserve-content>
Hello World from simple demo
</template>
</print-contents-html>
</template>
...
Then it works!

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

Issue with data binding in Polymer templates

I have a page where I am binding an array to input fields. Data binding seems to be working somewhat strange.
Please have a look at below example
<!doctype html>
<html>
<head>
<script src='bower_components/webcomponentsjs/webcomponents-lite.js'></script>
<link rel='import' href='bower_components/polymer/polymer.html'>
<link rel='import' href='bower_components/paper-input/paper-input.html'>
</head>
<body unresolved>
<dom-module id='base-page'>
<template>
<template is='dom-repeat' as='cell' items='{{data}}'>
<paper-input value='{{cell}}'></paper-input>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'base-page',
properties: {
data: {
type: Array,
value: function() {
return [0,0]
}
}
}
});
</script>
<base-page></base-page>
</body>
If I edit the content in the second paper-input, data is changed in both. If I however initialize my data array to e.g. [0, 1], then the cells apparently looks different to start with and therefore it is able to differentiate between the cells and data binding seems to work. Whats the issue?, but more importantly, how can I make it work?
Cheers and thanks :-)
AFAIK plain numbers don't work well in arrays. Especially here where Polymer can't tell them apart properly if they have the same value.
Wrap them in objects like
return [{value: 0}, {value: 0}]
and then use it like
<paper-input value='{{cell.value}}'></paper-input>

template repeat in polymer 1.0

I've created a test polymer element where in I was figuring out how to use use arrays in templates. My code does not work and the documentation for 1.0 doesn't really talk much about how to use repeat in template tags.
my element:
<!-- Imports polymer -->
<link rel="import" href="polymer/polymer.html">
<!-- Defines element markup -->
<dom-module id="my-element" >
<template>
<style>
my-element
</style>
<h2>{{data}}</h2>
<ul>
<template repeat={{column in columns}} bind>
<li>{{column}}</li>
</template>
</ul>
</template>
</dom-module>
<!-- Registers custom element -->
<script>
Polymer({
is: 'my-element',
// Fires when an instance of the element is created
created: function() {
},
// Fires when the local DOM has been fully prepared
ready: function() {},
// Fires when the element was inserted into the document
attached: function() {},
// Fires when the element was removed from the document
detached: function() {},
// Fires when an attribute was added, removed, or updated
attributeChanged: function(name, type) {
alert("changed");
},
properties:{
data :String,
columns:Array
}
});
</script>
and the index.html page where I'm using the element:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><my-repo></title>
<!-- Imports polyfill -->
<script src="webcomponents-lite.min.js"></script>
<!-- Imports
custom element -->
<link rel="import" href="my-element.html">
<!-- Runs custom element -->
<my-element users = '{{[1,2,3,4]}}' data="This is a polymer table"></my-element>
Please let me know what's wrong with my code!!
You have to use
<template is="dom-repeat" items="{{users}}">
<li>{{item}}</li>
</template>
And in main file:
<my-element users="[1,2,3,4]" data="This is a polymer table"></my-element>
You can search Youtube for Polycast, a series by Google Developers where they're talking about Polymer for beginners and showing cool tricks.
Polymer 1.0 does not allow expressions in data binding. The problem is in:
<my-element users = '{{[1,2,3,4]}}' ...>
You need to replace {{[1,2,3,4]}} with a property. Something like this:
<template is="dom-bind">
<my-element users = '{{myarray}}' data="This is a polymer table"></my-element>
</template>
<script>
(function() {
var template = document.querySelector('template[is="dom-bind"]');
template.myarray = [1,2,3,4];
})();
</script>

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>