Iron ajax not working - polymer

I'm trying to get iron-ajax working but thus far without success.
I have added the component to my bower.json, ran bower install, imported it in the html file I want it to use in and tried to add it to a template.
Usually my IDE auto-completes all Polymer tags just fine but this one just won't work. When I open the page I get the following error: Uncaught ReferenceError: Invalid left-hand side in assignment which points to the " this.$.add-contact.contentType = "application/json";" line, see below.
I am wondering if the element is properly imported or if I'm missing something obvious.
Here's my code:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/paper-input/paper-input.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">
<dom-module id="contact-form">
<template>
<style>
</style>
<h1>My New Contact</h1>
<paper-input label="Name" value="{{name}}"></paper-input>
<paper-input label="Phone Number:" value="{{telnr}}"></paper-input>
<paper-button on-tap="addContact">Add Contact</paper-button>
<iron-ajax id="add-contact"
method="POST"
url="/cgi-bin/add-contact.py"
handle-as="json"
on-response="addContact_ResponseHandler">>
</iron-ajax>
</template>
<script>
Polymer({
is: "contact-form",
addContact: function () {
this.$.add-contact.contentType = "application/json";
this.$.add-contact.body = {naam: this.name, telnr: this.telnr};
this.$.add-contact.generateRequest();
console.log("Contact: " + this.name+ ", " + this.telnr);
}
addContact_ResponseHandler:
function(request_confirm) {
console.log("Response: " + request_confirm);
}
});
</script>
</dom-module>

this.$.add-contact is actually equivalent to this.$.add - contact (a subtraction of a symbol named contact from the element with an ID of add (neither of which exist).
To access <iron-ajax id="add-contact"> imperatively, use this.$['add-contact'].

Related

How to implement custom filters in Polymer 1.7.x

I am trying to implement a custom filter using Polymer v1.7.0 currently. However, it does not work at all; when I try to use a filter the output is just the raw expression, unprocessed.
I have tried it like it's done here: https://github.com/PolymerLabs/polymer-patterns/blob/master/snippets/filters/using-custom-filters.html but using this code:
<div id="toFixed">{{10.123456789 | toFixed(2)}}</div>
only results in
{{10.123456789 | toFixed(2)}} in the resulting document.
Is my linked source outdated? I couldn't find any valuable information in the Polymer docs so a nudge into the right the direction is appreciated.
You don't need pipe in Polymer 1.x to achieve this. You can directly call an function and pass it the value that you want to
<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
<dom-module id="my-element">
<template>
{{format(myVal)}}
<br>{{format("hello")}}
</template>
</dom-module>
<script>
Polymer({
is: "my-element",
properties: {
myVal: {
type: String,
value: "Hi"
}
},
format: function(input) {
return input + " John";
}
});
</script>
<my-element></my-element>

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!

Modify iron-form JSON before submitting

I'm wondering if it is possible to edit the JSON file of an iron-form before submitting it? For instance, if I want to add an array which doesn't come from any of the form input, or if I want to add a unique key in it...
If it is possible, I believe it would be during the form pre-submit, but the documentation says nothing about "how to intercept the JSON" or something like that.
Thanks!
You could modify the iron-form's request object in the iron-form-presubmit event handler. For POST requests, the form data is stored in the body, which you would access by this.$.form.request.body. For other request types, the data is in this.$.form.request.params. This example adds an array to the request's body:
// template
<form is="iron-form" id="form" on-iron-form-presubmit="_presubmit" method="post">...</form>
// script
_presubmit: function(e) {
var body = this.$.form.request.body;
body['newkey'] = [1,2,3];
console.log('body', body);
},
<head>
<base href="https://polygit.org/polymer+1.11.3/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">
<link rel="import" href="iron-form/iron-form.html">
<link rel="import" href="paper-input/paper-input.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<x-foo></x-foo>
<dom-module id="x-foo">
<template>
<form is="iron-form" id="form" on-iron-form-presubmit="_presubmit" method="post" action="//httpbin.org/post">
<paper-input name="name" label="name"></paper-input>
<paper-button on-tap="_submit">Submit</paper-button>
</form>
</template>
<script>
HTMLImports.whenReady(function() {
Polymer({
is: 'x-foo',
_presubmit: function(e) {
var body = this.$.form.request.body;
body['newkey'] = [1,2,3];
console.log('body', body);
},
_submit: function() {
this.$.form.submit();
}
});
});
</script>
</dom-module>
</body>
codepen

Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'paper-button'

I'm using polymer 1.2.1
I'm trying to create two polymer elements paper-button & paper-input.
I had imported following in head
<script src="third-party/js/bower/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="third-party/html/bower/polymer/polymer.html">
<link rel="import" href="third-party/html/bower/paper-button/paper-button.html">
<link rel="import" href="third-party/html/bower/paper-input/paper-input.html">
and added following in body
<paper-button>Flat button</paper-button>
<paper-button raised>Raised button</paper-button>
<paper-button noink>No ripple effect</paper-button>
<paper-button toggles>Toggle-able button</paper-button>
<paper-input label="total">
<div prefix>$</div>
<paper-icon-button suffix icon="clear"></paper-icon-button>
</paper-input>
<script>
Polymer({
is: "paper-button",
// add a callback to the element's prototype
created: function() {
console.log("inside pol1");
this.textContent = "I'm a proto-element!"
}
});
Polymer({
is: "paper-input",
// add a callback to the element's prototype
created: function() {
console.log("inside pol2");
this.textContent = "I'm a proto-elemente2!"
}
});
</script>
I'm expecting a change in text of respective elements with some console but none of these happens. I get an error saying
"Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'paper-button'. A type with that name is already registered."
I'm not quite sure what you are trying to achieve, but the answer to your question is this:
Your paper-input and paper-button have already been registered into Polymer by your <link rel="import"> tags in your <head> section, so naturally when you try to re-register them using Polymer({is:"paper-button"...}), it fails...
I also wouldn't recommend overriding a packaged element's created() callback - if you want to do your own custom tasks, create a new custom element that wraps your target element, and then call your new element instead.

Polymer 1.0 Extending Elements - paper-dialog with custom element

I am am trying to create a custom element that plays a youtube video in paper-dialog. So videoPlayer = Polymer.dom(this.root).querySelector('video-player'); inherits/has access to that paper-dialogs open method, I am trying to extend my custom element. It isn't working, but hopefully I am on the right track and someone can show me correctly.
I am using Polymer 1.0, but I only have https://www.polymer-project.org/0.5/docs/polymer/polymer.html#extending-other-elements to go by for extending elements.
<link rel="import" href="../bower_components/paper-dialog/paper-dialog.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/google-youtube/google-youtube.html">
<link rel="import" href="../bower_components/polymer/polymer.html">
<dom-module id="video-player">
<template>
<div class="layout horizontal">
<paper-button dialog-dismiss>
<paper-icon-button icon="arrow-back"></paper-icon-button>
</paper-button>
</div>
<div style="height: 100%; width: 100%">
<google-youtube style="height: 100%;"
video-id="YMWd7QnXY8E"
rel="1"
start="5"
playsinline="0"
controls="2"
showinfo="0"
width="100%"
height="100%"
autoplay="1">
</google-youtube>
</div>
</template>
<script>
Polymer({
is: "video-player"
});
</script>
<paper-dialog name="video-player" extends="video-player">
<template>
<shadow></shadow>
</template>
<script>
Polymer();
</script>
</paper-dialog>
<video-player></video-player>
As was mentioned in the comments, you can't yet extend custom elements, so the existing pattern (or at least the one I use) is to make use of behaviors wherever possible and wrappers wherever not.
e.g.
<dom-module id="popup-video-player">
<template>
<video-player></video-player>
</template>
<script>
Polymer({
is: 'popup-video-player',
behaviors: [Polymer.PaperDialogBehavior],
...
});
</script>
</dom-module>
Now you can use <popup-video-player> just like a paper-dialog.
I know it stinks because if video-player has a bunch of properties that you want access to, you have to copy them in the popup-video-player element's API, which is not exactly DRY.
If you look at the paper-input source, you'll see them doing the same thing. It's obvious that they want to extend iron-input, but they can't so you get things like this:
<input is="iron-input" id="input"
aria-labelledby$="[[_ariaLabelledBy]]"
aria-describedby$="[[_ariaDescribedBy]]"
disabled$="[[disabled]]"
title$="[[title]]"
... >
As a side note, you could always hook into the <video-player>s "properties" property and make the API additions programatically.
maybe something like this would work: (untested!)
Polymer({
...
properties: (function () {
var prop = {
//special properties specific to the pop up version of video-player
//..obviously be careful to avoid name space conflicts.
};
var video_player = document.createElement('video-player');
video_player.properties.keys().forEach( function(key) {
props[key] = video_player[key];
});
return props;
}()),
});