I am trying to get the reddit topic results from AJAX request and it seems my current approach of passing the posts results is wrong.
Currently I have created three web components, separate service for the ajax requests which passes the response via attribute.
Separate search component which has text input field changes the category for the 'service'.
The search component pass the posts to listing service.
The problem is with the passing posts data from search component to list component.
reddit-post-service.html
<link rel="import" href="../components/polymer/polymer.html">
<link rel="import" href="../components/core-ajax/core-ajax.html">
<polymer-element name="reddit-post-service" attributes="posts subreddit">
<template>
<style>
:host {
display: none;
}
</style>
<core-ajax id="ajax"
url="http://www.reddit.com/r/{{subreddit}}/new.json"
on-core-response="{{postsLoaded}}"
on-core-error="{{handleError}}"
auto
handleAs="json">
</core-ajax>
</template>
<script>
Polymer('reddit-post-service', {
created: function() {
console.log('Reddit post service created');
this.posts = [];
},
postsLoaded: function() {
// Make a copy of the loaded data
this.posts = this.$.ajax.response.data.children
.map(function (post) {
return post.data;
});
},
handleError: function () {
this.posts = [];
}
});
</script>
</polymer-element>
reddit-search.html
<link rel="import" href="../components/polymer/polymer.html">
<link rel="import" href="../components/paper-input/paper-input.html">
<link rel="import" href="../components/paper-button/paper-button.html">
<link rel="import" href="reddit-post-service.html">
<polymer-element name="reddit-search" attributes="posts">
<template>
<style>
paper-button.search {
background-color: #19D820;
}
</style>
<paper-input label="subreddit name" tabindex="0" value="{{subreddit}}"></paper-input>
<paper-button label="Search" tabindex="1" class="search"></paper-button>
<reddit-post-service subreddit="{{subreddit}}" posts="{{posts}}"></reddit-post-service>
</template>
<script>
Polymer('reddit-search', {
subreddit: 'programming',
// initialize the element's model
ready: function() {
}
});
</script>
</polymer-element>
post-list.html
<link rel="import" href="../components/polymer/polymer.html">
<link rel="import" href="../post-service/post-service.html">
<link rel="import" href="post-card.html">
<polymer-element name="post-list" attributes="show posts">
<template>
<style>
:host {
display: block;
width: 100%;
}
</style>
<div layout vertical center>
<template repeat="{{post in posts}}">
<!-- Never reach this block -->
<span>{{post}}</span>
</template>
</div>
</template>
<script>
Polymer({
});
</script>
</polymer-element>
index.html
<!doctype html>
<html>
<head>
<title>unquote</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<script src="../components/platform/platform.js"></script>
<link rel="import" href="../components/font-roboto/roboto.html">
<link rel="import" href="../components/core-header-panel/core-header-panel.html">
<link rel="import" href="../components/core-toolbar/core-toolbar.html">
<link rel="import" href="../components/paper-tabs/paper-tabs.html">
<link rel="import" href="../components/paper-tabs/paper-tabs.html">
<link rel="import" href="post-list.html">
<link rel="import" href="reddit-search.html">
<link rel="import" href="name-tag.html">
<style>
</head>
<body unresolved>
<core-header-panel>
<core-toolbar>
<paper-tabs valueattr="name" selected="new" self-end>
<paper-tab name="new">NEW</paper-tab>
<paper-tab name="favorites">FAVORITES</paper-tab>
</paper-tabs>
<reddit-search posts="{{posts}}"></reddit-search>
</core-toolbar>
<!-- <name-tag></name-tag> -->
<!-- main page content will go here -->
<div class="container" layout vertical center>
<post-list show="all" posts="{{posts}}"></post-list>
</div>
</core-header-panel>
<script>
</script>
</body>
</html>
Data-binding via '{{ }}' only works in the context of a template. Your index.html attempts to use binding outside of a template.
You can fix this by making your main application itself a polymer-element, by using some other system for propagating the data, or by using an auto-binding template, like this:
<template is="auto-binding">
<core-header-panel flex>
<core-toolbar>
<paper-tabs valueattr="name" selected="new" self-end>
<paper-tab name="new">NEW</paper-tab>
<paper-tab name="favorites">FAVORITES</paper-tab>
</paper-tabs>
<reddit-search posts="{{posts}}"></reddit-search>
</core-toolbar>
<div class="container" layout vertical center>
<post-list show="all" posts="{{posts}}"></post-list>
</div>
</core-header-panel>
</template>
See http://jsbin.com/xahoc/2/edit
Related
Problem:
Just started updating my Polymer PWA to Polymer version 2
and now getting the same error for each element in the console and nothing loads.
Uncaught TypeError: Class extends value undefined is not a constructor or null
Similar issues had something to do with circular dependencies but I am not really sure why this happens, what it exactly means and how to resolve it. Maybe someone can clear things up here!?
Idea:
I might be using some sort of mix of Polymer2 & it's hybrid mode as I am still using the dom-if and imported the bower_components/polymer/lib/elements/dom-if.htmlHowever, I don't think this is causing the error as the console points to class MyApp extends Polymer.Element
Example 1:
<!-- import CSS mixin shim -->
<link rel="import" href="bower_components/shadycss/apply-shim.html">
<!-- import custom-style -->
<link rel="import" href="bower_components/polymer/lib/elements/custom-style.html">
<!-- import template repeater -->
<link rel="import" href="bower_components/polymer/lib/elements/dom-if.html">
<link rel="import" href="bower_components/polymer/polymer-element.html">
<!-- Polymer Imports -->
<link rel="import" href="bower_components/polymer/polymer.html">
<!-- CustomElements -->
<link rel="import" href="src/customElements/custom-icons.html">
<link rel="import" href="my-landingpage.html">
<link rel="import" href="my-yole.html">
<dom-module id="my-app">
<template>
<style>
:host > * {
display: block;
}
</style>
<template is="dom-if" if="[[!user]]">
<my-landingpage></my-landingpage>
</template>
<template is="dom-if" if="[[user]]">
<my-yole></my-yole>
</template>
</template>
<script>
class MyApp extends Polymer.Element {
static get is() { return 'my-app'; }
}
customElements.define(MyApp.is, MyApp);
</script>
</dom-module>
Example 2 with the same Error:
<!-- import CSS mixin shim -->
<link rel="import" href="../../bower_components/shadycss/apply-shim.html">
<!-- import custom-style -->
<link rel="import" href="../../bower_components/polymer/lib/elements/custom-style.html">
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
<!-- Polymer Imports -->
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/app-layout/app-grid/app-grid-style.html">
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
<link rel="import" href="../../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="custom-icons.html">
<!-- Custom Elements & Style -->
<dom-module id="my-footer">
<template>
<style include="app-grid-style">
:host > * {
display: block;
--app-grid-columns: 3;
--app-grid-gutter: 24px;
}
</style>
<div>
<ul id="footer" class="app-grid">
<li>Terms of use</li>
<li>
<a href="https://www.facebook.com">
<iron-icon icon="custom-icons:facebook"></iron-icon>
</a>
<a href="https://www.instagram.com">
<iron-icon icon="custom-icons:instagram"></iron-icon>
</a>
</li>
<li on-tap="openPolicy">Privacy Policy</li>
</ul>
</div>
<paper-dialog id="policyDialog" with-Backdrop>
<h2>Privacy Policy</h2>
<h2>Privacy Policy for yogiyolie.com </h2>
</paper-dialog>
</template>
<script>
class MyFooter extends Polymer.Element {
static get is() { return 'my-footer'; }
constructor() {
super();
}
connectedCallback() {
super.connectedCallback();
this._updateGridStyles = this._updateGridStyles || function() {
this.updateStyles();
}.bind(this);
window.addEventListener('resize', this._updateGridStyles);
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener('resize', this._updateGridStyles);
}
openPolicy() {
this.$.policyDialog.toggle();
}
}
customElements.define(MyFooter.is, MyFooter);
</script>
</dom-module>
So what I forgot to mention is that I am using Firebase to serve and deploy my app.
I just noticed that I have 2 bower-components folder.Firebase requires the components inside the public folder to ship them when deploying the app.
When updating the bower-components I was just simply creating a new folder in the top level directory instead of changing the existing one in my public folder. Although this seems kind of obvious I will leave the question online in case someone should be having the same issue one day.
Hopefully somebody can help me better understanding using app-router with Polymer. I have the following files - index.html, app.html and updates.html.
Everything is working as it should with the main layout appearing when I navigate to the root of the domain but nothing appears in the content area where I am trying to render the contents of the updates.html file using the app-router element.
Any help is much appreciated
index.html
<html>
<head>
<title>Example App</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<link rel="stylesheet" href="styles/main.css">
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="elements/app.html">
</head>
<body fullbleed unresolved>
<example-app></example-app>
</body>
</html>
app.html
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/core-icons/core-icons.html">
<link rel="import" href="../bower_components/core-item/core-item.html">
<link rel="import" href="../bower_components/core-scaffold/core-scaffold.html">
<link rel="import" href="../bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="../bower_components/core-menu/core-menu.html">
<link rel="import" href="../bower_components/app-router/app-router.html">
<polymer-element name="example-app">
<template>
<core-scaffold id="scaffoldPanel">
<core-header-panel navigation flex>
<core-toolbar id="navheader" class="tall">
<img class="middle profile" src="../images/main-carer.png">
</core-toolbar>
</core-header-panel>
<core-toolbar tool flex>
<div id="main-title" flex>Example App</div>
<core-icon icon="search"></core-icon>
</core-toolbar>
<div class="content">
<app-router>
<app-route path="/" import="elements/updates.html" element="app-updates"></app-route>
</app-router>
</div>
</core-scaffold>
</template>
</polymer-element>
updates.html
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="app-updates">
<template>
<div vertical layout style="height:50px;">
<div flex class="home-update-menu"><h4>UPDATES</h4></div>
</div>
<div>Updates appear here</div>
</template>
</polymer-element>
Firefox goes as far as the then it keeps "loading" but does not load any component or anything at all.
<!doctype html>
<html>
<head>
<title class="titulo"></title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<script src="http://www.polymer-project.org/components/platform/platform.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<link rel="import" href="http://www.polymer-project.org/components/font-roboto/roboto.html">
<link rel="import" href="http://www.polymer-project.org/components/core-ajax/core-ajax.html">
<link rel="import" href="http://www.polymer-project.org/components/core-icon-button/core-icon-button.html">
<link rel="import" href="http://www.polymer-project.org/components/core-icons/core-icons.html">
<link rel="import" href="http://www.polymer-project.org/components/core-icon/core-icon.html">
<link rel="import" href="http://www.polymer-project.org/components/core-drawer-panel/core-drawer-panel.html">
<link rel="import" href="http://www.polymer-project.org/components/core-header-panel/core-header-panel.html">
<link rel="import" href="http://www.polymer-project.org/components/core-toolbar/core-toolbar.html">
<link rel="import" href="http://www.polymer-project.org/components/core-viva/core-viva-item.html">
<link rel="import" href="http://www.polymer-project.org/components/core-viva/core-viva-submenu.html">
<link rel="import" href="http://www.polymer-project.org/components/core-menu/core-submenu.html">
<link rel="import" href="http://www.polymer-project.org/components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="http://www.polymer-project.org/components/paper-shadow/paper-shadow.html">
<link rel="import" href="http://www.polymer-project.org/components/paper-button/paper-button.html">
<link rel="import" href="http://www.polymer-project.org/components/paper-fab/paper-fab.html">
<script src="https://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="pagina.js"></script>
<link rel="stylesheet" href="pagina.css">
</head>
<body fullbleed>
<core-ajax url="" handleAs="json"></core-ajax>
<core-drawer-panel drawerWidth="320px" >
<core-header-panel drawer mode="standard" >
<paper-shadow z="2">
<core-toolbar id="topo-do-menu-lateral" class="medium-tall" >
<div id="toolbar-content"></div>
</core-toolbar>
<core-menu class="menulateral" id="menulateral" z="1" selected="0"></core-menu>
</paper-shadow>
</core-header-panel>
<core-header-panel id="main-content-header-panel" mode="waterfall" class="" main>
<!-- topo com tÃtulo -->
<core-toolbar id="topo-do-titulo" class="medium-tall middleJustify">
<paper-icon-button id="navicon" icon="menu" class="middle"></paper-icon-button>
<div id="titulo" class="indent middle" flex></div>
<paper-fab id="viva-close-button" icon="close" class="middle"></paper-fab>
<paper-shadow z="1"></paper-shadow>
</core-toolbar>
<div id="conteudo" class="indent" flex vertical layout center>
<responsive-embed id="responsiveEmbedContent">
</responsive-embed>
</div>
</core-header-panel>
</core-drawer-panel>
</body>
</html>
Its all i have besides the style.css (which i can attach if you think it might help, i even copied all imports to the index.html because FF was blabing about it.
Hope someone can help me.
I believe it has something to do with Firefox same-origin policy for Ajax calls.
Have you tried setting up a web server on your localhost to serve index.html?
so i just found out about polymer and it looks realy cool but the thing is i couldn't figure out if its using javascript or its own unique language.
so what script language polymer using? i like angular and i saw that polymer script is like angular script so i didn't realized if im suppose to use javascript angular or polymer script...
yo-greeting file:
<link rel="import" href="../bower_components/polymer/polymer.html">
<polymer-element name="yo-greeting" attributes="">
<template>
<style>
/* styles for the custom element itself - lowest specificity */
:host { display: block; }
/*
style if an ancestor has the different class
:host-context(.different) { }
*/
.imgWidth {
width: 100%;
}
core-header-panel {
height: 100%;
overflow: auto;
-webkit-overflow-scrolling: touch;
}
core-toolbar {
background: #03a9f4;
color: white;
}
#tabs {
width: 100%;
margin: 0;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
</style>
<img src="../images/lion.jpg" alt="" class="imgWidth" />
<paper-tabs selected="{{selectedPage}}">
<paper-tab>TAB 1</paper-tab>
<paper-tab>TAB 2</paper-tab>
<paper-tab>TAB 3</paper-tab>
</paper-tabs>
<core-pages selected="{{selectedPage}}">
<div class="red_tab">One</div>
<div class="blue_tab">Two</div>
<div class="black_tab">Three</div>
</core-pages>
</template>
<script>
Polymer({
selectedPage: 1
});
</script>
</polymer-element>
index file:
<!doctype html>
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Polymer WebApp</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild-->
<script src="bower_components/platform/platform.js"></script>
<script src="bower_components/angular/angular.js"></script>
<!-- build:vulcanized elements/elements.vulcanized.html -->
<link rel="import" href="elements/elements.html">
<link rel="import" href="bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="bower_components/core-media-query/core-media-query.html">
<link rel="import" href="bower_components/core-list/core-list.html">
<link rel="import" href="bower_components/paper-radio-button/paper-radio-button.html">
<link rel="import" href="bower_components/core-selector/core-selector.html">
<link rel="import" href="bower_components/core-pages/core-pages.html">
<!-- endbuild-->
</head>
<body unresolved>
<div class="hero-unit">
<yo-greeting></yo-greeting>
<!-- <p>You now have</p>
<yo-list></yo-list> -->
</div>
<!-- build:js scripts/app.js -->
<script src="scripts/app.js"></script>
<!-- endbuild-->
</body>
</html>
elements file:
<link rel="import" href="yo-list.html">
<link rel="import" href="yo-greeting.html">
i want that when i press on one of these tabs the core-pages will switch using polymer.
how do i do that the best way possible?
also - why my core-pages is not like that demo in the polymer site - http://www.polymer-project.org/docs/elements/core-elements.html#core-pages?
i installed it using bower and linked it just like the i linked the paper-tabs. its just showing one and does not switch when pressed.
thanks for all your help.
First of all there is no such thing as "Polymer Script". You write the code for your custom components in a language like JavaScript or Dart (or CoffeeScript or TypeScript or...)
There is a concept called "Polymer Expressions", which is the syntax inside the mustache ({{ }}) binding expressions. This is a subset of the JavaScript language with some additions like filters and they are similar to the AngularJS binding expressions.
To switch between the pages with your tabs, simply set up a binding between the selected properties of these elements. Currently you are setting the selected attribute of <core-pages> to 0, but nothing is changing it later on.
<polymer-element name="yo-greeting">
<template>
...
<paper-tabs selected="{{selectedPage}}">
<paper-tab>TAB 1</paper-tab>
<paper-tab>TAB 2</paper-tab>
<paper-tab>TAB 3</paper-tab>
</paper-tabs>
<core-pages selected="{{selectedPage}}">
<div class="red_tab">One</div>
<div class="blue_tab">Two</div>
<div class="black_tab">Three</div>
</core-pages>
</template>
<script>
Polymer('yo-greeting', {
selectedPage: 0
});
</script>
</polymer-element>
Whenever the tab selection changes this automagically updates the selected core page. This is done by binding the selected attributes to the selectedPage property of the yo-greeting element.
I'm trying to use paper-tabs inside new element (tabs-list) but after print tabs I can't use querySelector to change selected one.
Element code (without style):
<link rel="import" href="../components/polymer/polymer.html">
<link rel="import" href="../sprint-service/sprint-service.html">
<link rel="import" href="../components/paper-tabs/paper-tabs.html">
<polymer-element name="tab-list" attributes="show">
<template>
<sprint-service id="service" sprints="{{sprints}}"></sprint-service>
<paper-tabs selected="all" valueattr="name" self-end>
<paper-tab name="all">ALL</paper-tab>
<template repeat="{{sprint in sprints}}">
<paper-tab name="{{sprint.id}}">{{sprint.id}}</paper-tab>
</template>
</paper-tabs>
</template>
<script>
Polymer('tab-list', {
ready: function() {
var tabs = document.querySelector('paper-tabs');
tabs.addEventListener('core-select', function() {
list.show = tabs.selected;
})
}
});
</script>
</polymer-element>
Index.html code (whitout style):
<!doctype html>
<html>
<head>
<title>unquote</title>
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<script src="../components/platform-dev/platform.js"></script>
<link rel="import" href="../components/font-roboto/roboto.html">
<link rel="import"
href="../components/core-header-panel/core-header-panel.html">
<link rel="import"
href="../components/core-toolbar/core-toolbar.html">
<link rel="import" href="tab-list.html">
<link rel="import" href="post-list.html">
</head>
<body unresolved touch-action="auto">
<core-header-panel>
<core-toolbar>
<tab-list></tab-list>
</core-toolbar>
<div class="container" layout vertical center>
<post-list show="all"></post-list>
</div>
</core-header-panel>
<script>
var list = document.querySelector('post-list');
</script>
</body>
</html>
But
querySelector('paper-tabs') = *null*
I've tried to put the eventListener in index.html but I have the same problem.
can anyone tell me where the problem is?
Thank you very much!
document.querySelector('paper-tabs');
doesn't find the paper-tabs element, because it is hidden inside the shadow DOM of the tab-list element.
You can simply give paper-tabs an id, say tabs, and access it like so
this.$.tabs
(See http://www.polymer-project.org/docs/polymer/polymer.html#automatic-node-finding.)
There is also the option to access the shadow DOM directly
this.shadowRoot.querySelector('paper-tabs');
If you only want to listen for changes on the paper-tabs selection, you can use a change watcher:
<paper-tabs selected="{{currentTab}}">
Polymer('tab-list', {
currentTab: 'all',
currentTabChanged: function() {
console.log(this.currentTab);
}
});
(See http://www.polymer-project.org/docs/polymer/polymer.html#change-watchers)
<template is="dom-repeat" items="{{dataobject}}">
<div on-tap="_showdetail">
<iron-collapse id="collapse">??</iron-collapse>
</div>
</template>
And to toggle the iron-collapse elements inside the dom-repeat I use
_showdetail: function(e){
Polymer.dom(e.currentTarget).querySelector('#collapse').toggle();
},