Hi I'm trying to execute a basic polymer program. Getting the below exception at step var el = new HelloElement();. Also the element itself is not attached to the page.
Exception
Uncaught TypeError: Illegal constructor
at PropertyAccessors (property-accessors.html:119)
at TemplateStamp (template-stamp.html:119)
at PropertyEffects (property-effects.html:1075)
at PolymerElement (element-mixin.html:459)
at GestureEventListeners (gesture-event-listeners.html:40)
at LegacyElement (legacy-element-mixin.html:69)
at PolymerGenerated (class.html:137)
at (index):18
at html-imports.js:580
at html-imports.js:617
CODE
<!DOCTYPE html>
<html>
<head>
<script src="bower_components/webcomponentsjs/webcomponents-lite.js"> </script>
<link rel="import" href="bower_components/polymer/polymer.html"/>
</head>
<body>
<script>
HTMLImports.whenReady( function () {
HelloElement = Polymer.Class({
is: "hello-element",
created: function () {
this.textContent = "Hello World";
}
});
document.registerElement('hello-element', HelloElement);
var el = new HelloElement();
document.querySelector("body").appendChild(el);
})
</script>
</body>
</html
Try using the new class syntax as below:
HTMLImports.whenReady(function() {
class MyElement extends Polymer.Element {
static get is() { return 'my-element'; }
static get properties() {
return {
prop: {
type: String
}
}
}
constructor() {
super();
this.prop = 'my-element'
}
}
customElements.define(MyElement.is, MyElement);
var el = new MyElement();
el.textContent = 'my-element';
document.querySelector("body").appendChild(el);
});
JSBin: http://jsbin.com/vefelacada/edit?html,console,output
See more informations at: https://www.polymer-project.org/2.0/docs/devguide/registering-elements
=== Edit
If you really want to use Polymer 1.0 syntax, you should probably do something like: (not 100% sure what the error really means)
Polymer({
is: "hello-element",
});
var el = document.createElement("hello-element");
document.querySelector("body").appendChild(el);
el.textContent = 'my-element';
http://jsbin.com/zihayumaqo/edit?html,console,output
Related
I'm trying to bind the values using an object reference like this:
this.set('state', tab1Data);
but values are not binding with respective input fields.
We are using the polymer 3.x version
It depends very much on where you bind your data and how you bind it.
As you provide not so much information on the concrete context, I would guess, that you bind your data, outside the element ths calls this.set('state', ...) .
Then your property needs to have the notify-flag been set to true, otherwise changes won't be propagated outside.
The following code shows this behavior:
<html>
<head>
<script src="https://unpkg.com/#webcomponents/webcomponentsjs#latest/webcomponents-loader.js"></script>
</head>
<body>
<script type="module">
import {PolymerElement, html} from 'https://unpkg.com/#polymer/polymer/polymer-element.js?module';
import 'https://unpkg.com/#polymer/paper-button/paper-button.js?module';
class MyElement extends PolymerElement {
static get properties() {
return {
someData: {
type: Object,
value: () => {return {}},
notify: true
},
otherData: {
type: Object,
value: () => {return {}},
notify: false
},
counter: Number
}
}
constructor() {
super();
this.counter = 0;
}
static get template() {
return html`
<style> :host { display: block; } .mood { color: green; } </style>
Mood: <span class="mood">[[someData.mood]] ([[otherData.mood]])</span>
<paper-button raised on-click="setNewObject">set object</paper-button>
<paper-button raised on-click="setNewValue">set value</paper-button>
`;
}
setNewObject() {
this.counter++
const mood = `good [${this.counter}]`
this.set('someData', {mood: mood});
this.set('otherData', {mood: mood});
}
setNewValue() {
this.counter++
const mood = `better [${this.counter}]`
this.set('someData.mood', mood);
this.set('otherData.mood', mood);
}
}
customElements.define('my-element', MyElement);
class MySecondElement extends PolymerElement {
static get properties() {
return {
mood: String
}
}
static get template() {
return html`Web Components are <span>[[mood]]</span>!`;
}
}
customElements.define('my-second-element', MySecondElement);
class MyApp extends PolymerElement {
static get template() {
return html`
<my-element some-data="{{someData}}" other-data="{{otherData}}" ></my-element>
<h2>notify true</h2>
<my-second-element mood="[[someData.mood]]"></my-second-element>
<h2>notify false</h2>
<my-second-element mood="[[otherData.mood]]"></my-second-element>
`;
}
}
customElements.define('my-app', MyApp);
</script>
<my-app></my-app>
</body>
</html>
You should put the code on the value which set on the localstorage. I show it here.
import '#polymer/iron-localstorage/iron-localstorage.js';
....
<iron-localstorage name="user-info" value="{{userInfo}}" on-iron-localstorage-load-empty="initializeUserInfo"></iron-localstorage>
<vaadin-text-field id="test">
........
initializeUserInfo(){
this.set('userInfo', []);
}
ready(){
super.ready();
this.set('userInfo', this.$.test.value);
}
This is able to set data in the localstorage.
I have a lambda service that returns html to the client (i.e browser). However, the event listener doesn't work. Any idea why? Code is as follows:
const serverless = require('serverless-http');
const express = require('express');
const fetch = require('node-fetch');
const app = express();
app.get('/', function (req, res) {
var htmlText = `
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.7/webcomponents-loader.js"></script>
<script type="module" >
import {html, render} from 'https://unpkg.com/lit-html?module';
/**
* Adapted from the Ractive.js clock example: http://www.ractivejs.org/examples/clock/
*/
export class MyElement extends HTMLElement {
// Define a template
get flag() { return this._flag; }
set flag(v) { this._flag = v }
constructor() {
super();
this.attachShadow({mode: 'open'});
setInterval(() => {
if (!this.flag) {
this.flag = true;
render(this.render(), this.shadowRoot);
}
}, 1000);
}
// Render the template to the document
render(site) {
console.log("called")
return html\`
<style>
:host {
display: block;
padding: 0 15px;
border-right: 1px solid #333333;
line-height: 12px;
}
</style>
<button #click="${() => console.log('button was clicked')}">BUTTON</button>
\`
}
}
customElements.define('my-element', MyElement);
</script>
</head>
<body>
<p>Hello World</p>
<my-element></my-element>
</body>
</html>
`;
res.send(htmlText)
});
module.exports.handler = serverless(app);
looking at the shadowroot from Chrome dev tools, the button was incorrectly rendered as <button #click="() => console.log('button was clicked')">BUTTON</button>. Any idea what am I doing wrong? Thanks.
Inside shadow dom try to import litElement instead lit-html as lit-html lets you write HTML templates in JavaScript.
import {html, render} from 'https://unpkg.com/lit-element'
class MyElement extends LitElement {...
//index.html
<html>
<head>
<link rel="import" href="test-table.html">
</head>
<body>
<template is="dom-bind" id="index">
<test-table data="{{data}}" ></test-table>
</template>
</body>
</html>
Polymer({
is: "test-table",
properties : {
data : {type : Array},
}
/*I dont know where should I put this stuff
"queryForIds:"
"getByIds :"
"set:"
"length:0"
*/
});
<dom-module id="test-table">
<template>
<paper-datatable-card id="datatableCard" header="Users" page-size="10" data-source="{{data}}" id-property="_id" selected-ids="{{selectedIds}}">
<paper-datatable id="datatable" data='{{data}}' selectable multi-selection selected-items="{{selectedItems}}">
<paper-datatable-column header="Id" property="_id" sortable>
<template>
<span>{{value}}</span>
</template>
</paper-datatable-column>
</paper-datatable>
</paper-datatable-card>
</template>
</dom-module>
as part of single page application I am using “paper-datatable-card” in my own custom-tag. I able to display the records but I’m not getting where I have to put the code for pagination. And I don’t want to put all records into dataSource at a time.
Any help is appreciated,
Thank you,
Venkat.
From within your Polymer component, you can set data in the ready method:
ready: function() {
this.data = {
queryForIds: function(sort, page, pageSize){
// implement me
},
getByIds: function(ids){
// implement me
},
set: function(item, property, value){
// implement me
},
length:0
};
}
Your comment question:
So I am unable to put the code from lines 117 to 133 in my custom elements as it doesnt support dom-bind
Answer (in Polymer 2.0) you can do it in your component constructor all the methods and all the data variables:
class YourComponent extends Polymer.Element {
contructor() {
super();
//in case if you use paper-datatable-card
this.data = {
get: function (sort, page, pageSize) {
return new Promise((resolve, reject) => {
const exampleData = [
{ 'name': 'someName1' },
{ 'name': 'someName2' }
];
resolve(exampleData);
});
},
set: function(item, property, value){...},
length: 1
};
//in case if you use paper-datatable only then without get or set properties
this.data = [ { name: 'someName' } ];
}
}
I'm working for the first time with Angular.js. I already search too many articles in order to correct this error. I receive the following error when my Index.html is loaded:
Here is the code:
report-module.js
angular.module('reportTemplateApp', [
'reportTemplateApp.services',
'reportTemplateApp.controllers',
'ngRoute'
]).
config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when('/slide1/:auditId', {
templateUrl: 'slide1.html',
controller: 'MainSlideController',
controllerAs: 'main'
})
.when('/slide3/:auditId/sl/:slideId', {
templateUrl: 'slide3.html',
controller: 'CommonSlidesController',
controllerAs: 'commons'
});
$locationProvider.html5Mode(true);
}]);
report-controller.js
angular.module('reportTemplateApp.controllers', []).
controller('CommonSlidesController', '$routeParams', function ($scope, $routeParams, auditAPIservice) {
$scope.id = $routeParams;
$scope.slideId;
$scope.slide = [];
//CANCEL EDIT
$scope.cancelSave = function () {
$scope.mainList = $scope.backupList;
}
//SAVE DATA
$scope.saveSlide = function () {
try {
auditAPIservice.ItemsData($scope.mainList).then(function (response) {
if (response.message = "Success") {
}
else {
$scope.mainList = $scope.backupList;
}
});
} catch (ex) {
$scope.showToast('UPS! Something happen ' + ex.message);
}
}
//GET DATA
reportAPIservice.getSlide(2, 3).then(function (response) {
if (response.message = "Success") {
$scope.mainList = response.data.ReportSlideInfo
angular.copy($scope.mainList, $scope.backupList);
}
else {
//SOME ERROR SHOWING HERE
}
});
$scope.showToast = function (message) {
angular.element(document).ready(function () {
toast(message, 4000);
});
}
}).
Index.html
<!DOCTYPE html>
<html>
<head>
<script src="../Scripts/jquery-1.7.1.js"></script>
<script src="../Scripts/materialize/materialize.min.js"></script>
<title></title>
<link rel="stylesheet" type="text/css" href="../Content/materialize/materialize.css" />
</head>
<body ng-app="reportTemplateApp">
<script>
$(document).ready(function () {
$(".button-collapse").sideNav();
$('.collapsible').collapsible();
});
</script>
Text Link<br/>
<div ng-view></div>
<script src="../Scripts/angular.js"></script>
<script src="../Scripts/angular-route.js"></script>
<script src="~/Scripts/angular-resource.js"></script>
<script src="../Scripts/SPS/Report/report-module.js"></script>
<script src="../Scripts/SPS/Report/report-controller.js"></script>
<script src="../Scripts/SPS/Report/report-service.js"></script>
</body>
</html>
I don't know what it's wrong. Another thing, the error shows when I add in the Index page, if I remove it no error is present.
I was able to fix this. I had (I don't know why) in the project mixed versions of the angular.js(1.2.23) and angular-route.js (1.3.8). After change one with the same version of the other there is no error and routing works.
i have a polymer custom element like this
<script src="http://www.polymer-project.org/platform.js"></script>
<script src="http://www.polymer-project.org/polymer.js"></script>
<polymer-element name="my-foo" constructor="MyFoo" attributes="controller" noscript>
<template>
hello from {{options.name}}
</template>
<script>
Polymer({
get options() {
return this.controller.options;
}
});
</script>
</polymer>
<div id="container"></div>
<script>
document.addEventListener('polymer-ready',function() {
var foo = new MyFoo();
foo.controller = {
options : {
name : "here"
}
};
document.body.appendChild(foo);
});
</script>
attribute "controller" is expected to be a object having a property "options" of type object.
I can create a Instance of the custom element using
var foo = new Foo();
but i am unable to set the attribute "controller" which results in an error:
Uncaught TypeError: Cannot read property 'options' of undefined.
Sure - i could modify the options getter in the polymer component to be fail-safe like this :
...
get options() {
return this.controller ? this.controller.options : null;
}
...
But also in this case the custom element doesnt recognize the applied data.
Final question : How do I pass required attributes to an custom element constructor ?
One solution is to use a computed property:
<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'>
<polymer-element name="my-foo" constructor="MyFoo" attributes="controller" noscript>
<template>
hello from {{options.name}}
</template>
<script>
Polymer({
computed: {
options: 'controller.options'
}
});
</script>
</polymer-element>
<script>
document.addEventListener('polymer-ready',function() {
var foo = new MyFoo();
document.body.appendChild(foo);
foo.controller = {
options : {
name : "here"
}
}
});
</script>
You can even make the computed property just a call to a method. The key thing is that by doing it this way, Polymer can tell when to check if options has changed, because it knows the inputs necessary to compute options.
Polymer({
computed: {
options: 'getOptions(controller)'
},
getOptions: function(controller) {
return controller ? controller.options : null;
}
});