Should the on-change event in <paper-input> fire twice? - polymer

I've tried using <core-input> and "change" just fires once. Any ideas what could be the problem?
<polymer-element name="my-element">
<template>
<paper-input on-change="{{logChange}}">
</template>
<script> Polymer('my-element', {logChange: function(e){console.log('fired');}); </script>
</polymer-element>
Output:
fired
fired

This is a known issue - here's the corresponding Github issue:
https://github.com/Polymer/paper-input/issues/33
It's looking like this may actually be a bug in Chrome, for which a fix is in the works:
https://code.google.com/p/chromium/issues/detail?id=398527&thanks=398527&ts=1406661473

Related

Polymer Component not independent from each other?

Given this simplified component:
<dom-module id="poly-component">
<template>
<paper-button raised onclick="dialog.open()">Button</paper-button>
<paper-dialog id="dialog"><h1>Paper Dialog Here!</h1></paper-dialog>
</template>
<script>
Polymer({
is: 'poly-component'
})
</script>
which does nothing more than open the dialog on clicking the button.
This module works when it used once on a page.
But when it is inserted twice
[...]
<dom-module id="polyTest-app">
<template>
<h2>Hello [[prop1]]</h2>
<poly-component></poly-component>
<poly-component></poly-component>
</template>
[...]
it doesn't work anymore.
A click on the button leads to a:
(index):1 Uncaught TypeError: dialog.open is not a function
Am I missing something?
The code for this example can be found here: Example Code on GitHub
Your code cannot work because you're not binding the event handler correctly.
A built-in handler like onclick tries to execute the bit of code in global scope where dialog doesn't exist. Hence the error.
Here's how you can rewrite your code
<dom-module id="poly-component">
<template>
<paper-button raised on-click="_dialogOpen">Button</paper-button>
<paper-dialog id="dialog"><h1>Paper Dialog Here!</h1></paper-dialog>
</template>
<script>
Polymer({
is: 'poly-component',
_dialogOpen: function() {
this.$.dialog.open();
}
})
</script>
</dom-module>
First, notice how onclick changes to on-click - the Polymer event handling notation. PS. tap event is advised.
Second, you can only access other elements from code. Not directly in bindings. Hence the _dialogOpen function.
UPDATE
Ok, I know what's happening. When there is only one element with a given id, the browsers let's you use it simply by that id in global scope.
When you use Shady DOM, which I assume you do, two instances of your poly-component element render two <dialog id="dialog">. At this point window.dialog is not available anymore.
Again, with Polymer it's safer to use the this.$ notation aka Automatic node finding to reference elements in local DOM.

import multiple polymer web components in same file (getting error : .... a type with that name is already registered)

I just started using polymer for creating web-components.
When I import only one custom element everything is fine.
Now I want to use the polymer element iron-collapse in my custom web component and I want to import both of them in my HTML.
<link rel="import" href="../custom-accordion.html">
<link rel="import" href="../bower_components/iron-collapse/iron-collapse.html">
Both of the elements are positioned inside a dom-module Tag in their files:
<dom-module id="custom-accordion">
....content
</dom-module>
and
<dom-module id="iron-collapse">
....content
</dom-module>
When I want to import both I get the error :
Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'dom-module'. A type with that name is already registered.)
I think I have to use this dom-module tag in both, otherwise I can't create my web-component. Right?
Any ideas how to solve this issue?
dom-module is Polymer. The issue is polymer is running twice and trying to register dom-module element. In your code you are just using the dom-module element.
I am not sure how you are running your solution. Try below and see if it works
If you have included polymer in index.html, try removing it.
Try using polymer-starter-kit as your start. It takes care of most of these issues and comes packed with all the tools required to build a production ready polymer application. You can just focus on your code.
Do you have a Polymer-element in a script-tag inside your dom-module? You need to rename this as well :
<dom-module id="**yourElementName**">
<template>
[...]
</template>
<script>
Polymer({
is: "**yourElementName**",
[...]
})
</script>
</dom-module>

Call Method of Child Web Component

I'm really having difficulty trying to figure out how to call a function of a nested Polymer web component.
Here's the markup:
<rise-playlist>
<rise-playlist-item duration="5">
<rise-distribution distribution='[{"id":"VGZUDDWYAZHY"}]'></rise-distribution>
</rise-playlist-item>
</rise-playlist>
The rise-distribution component has a canPlay function that I would like to call from inside of rise-playlist.
The dom-module definition of rise-playlist looks like this:
<dom-module id="rise-playlist">
<template>
<content id="items" select="rise-playlist-item"></content>
</template>
</dom-module>
I can successfully access the rise-distribution element like this:
var distribution = Polymer.dom(this.$.items[0]).querySelector("rise-distribution");
However, when I try to call distribution.canPlay(), it says that distribution.canPlay is not a function.
I've defined the dom-module of rise-playlist-item like this:
<dom-module id="rise-playlist-item">
<content id="dist" select="rise-distribution"></content>
</dom-module>
Not sure if I need that <content> tag, although neither works.
Any ideas?
Thx.
I know that there have been a while but I am sure this problems still occurs as it is being viewed number of times.
Probably there is a problem with your component definition. Let me explain.
This is the way you put your child component inside DOM:
<your-child-component></your-child-component>
And and this should be the definition of your component:
Polymer({
is: 'your-child-component',
apiMethod: function() {
//some stuff
}
});
If you by mistake or due copy-paste error mistype the is: 'your-child-component' part, so it will not reflect the <your-child-component> you will get confused becouse your:
this.$$('your-child-component').apiMethod();
will tell you that there is no method you are willing to call.
Polymer correctly identified and selected from DOM <your-child-component> but if you have different is property (like for example is: your_child_component>) it will not attach its API to dom element you selected.
I hope that it will help if anyone ever will encounter this problem.

Polymer core-meta is already registered

I'm building an application with Polymer, and I'm having trouble creating my own component. The component I'm building is a login prompt.
<link rel="import" href="/static/bower_components/polymer/polymer.html">
<link rel="import" href="/static/bower_components/paper-button/paper-button.html">
<link rel="import" href="/static/bower_components/paper-input/paper-input.html">
<polymer-element name="login-prompt" attributes="">
<template>
<paper-input label="Email"></paper-input>
<paper-input label="Password" type="password"></paper-input>
<paper-button label="Login" affirmative></paper-button>
</template>
<script>
Polymer({});
</script>
</polymer-element>
But the moment I import more than one dependency (in this case paper-button and paper-input, I get this error in the console:
Error: DuplicateDefinitionError: a type with name 'core-meta' is already registered
It's coming from platform.js. Why is this error appearing? The demos in the documentation work exactly the same, but they behave normally.
Edit: Updated to load with absolute URLs, but I'm still getting the same error.
All righty, I figured it out. In my layout file, I was importing core-component-page. That file contains a definition for core-meta, along with some other elements that are already satisfied dependencies. I'm not sure why I had that in there, but I'd sure like to know what core-component-page is, and why it exists.

Polymer document.querySelector not working as expected

Either I am doing something horribly wrong or Polymer just doesn't like me. See following:
<polymer-element name="menu-paper-ui" noscript>
<template>
<paper-dialog heading="Dialog" transition="paper-dialog-transition-bottom">
[ .. ]
</paper-dialog>
<paper-button label="Dialog Bottom" on-tap="{{toggleDialog}}"></paper-button>
</template>
<script>
Polymer('menu-paper-ui', {
toggleDialog : function() {
var dialog = document.querySelector('paper-dialog');
console.log(dialog); //returns null
dialog.toggle();
}
})
</script>
</polymer-element>
Now, I have my reasons to use querySelector. So, if someone can tell me whats going wrong that will be great!
This question is nearly identical to Using querySelector to find nested elements inside a Polymer template returns null.
The short answer is that elements in a polymer-element's template are put into the ShadowDOM of that element, are not not visible to the anything outside of that element. This is so that you can control styling more easily, and element IDs are scoped.
You can either give the dialog an id and use Polymer's automatic node finding, or use this.shadowRoot.querySelector('paper-dialog').
The Problem is that you can not access the shadow DOM inside a custom element with document.querySelector. See my answer to a similar question.