polymer - can't load second component in test file - javascript

I have defined a component <my-panel> based on the polymer seed-element. I defined a second component <my-display> that contains a <my-panel> element.
I want to define a stubbed out version of my-panel.html alongside it in the my-panel component source: my-panel-stub.html.
When I'm writing the tests for <my-display>, I want to be able to swap out the contained <my-panel> element for a <my-panel-stub>. I can do this with:
replace("my-panel").with("my-panel-stub");
My only problem is that when I try to import my-panel-stub into the test file, after I've imported my-display, ie.
<link rel="import" href="../my-display.html">
<link rel="import" href="../bower_components/my-panel/my-panel-stub.html">
I get the following error when the tests execute:
Error: Failed to execute 'registerElement' on 'Document': Registration failed for type 'dom-module'. A type with that name is already registered.
It seems that the test file can only import one component?
I can resolve the issue by doing the html import of the stub inside the my-display component, ie:
<link rel="import" href="../my-panel/my-panel.html" />
<link rel="import" href="../my-panel/my-panel-stub.html" />
Then everything works. But the application code shouldn't be referencing this test-specific element.
Is there a better way to import the stub component directly into the test file?

Related

How to link a paper-button to another Polymer page?

I created a Polymer 2.0 app from the starter kit template in order to get to know the framework a little bit. I have a paper-button that should link to another page of the app. However, I still haven't figured out how to do so, since Polymer is loading pages dynamically via JavaScript rather than the browser just calling another one.
I also noticed something else strange: When I click a link in my app-drawer, the page changes automatically and the URL in my browser tab is being updated. However, when I hit refresh with that new URL in my address bar, I get a 404 error since the URL doesn't exist. So is there any way I can resolve this issue and link my button to another page?
This is my button:
<paper-button id="buttonStartQuiz" on-click="startQuiz">
go! <iron-icon icon="chevron-right"></iron-icon>
</paper-button>
And this is the JavaScript class that corresponds to the layout:
class MyView1 extends Polymer.Element {
static get is() { return 'my-view1'; }
/* This method is the listener for the button click */
startQuiz(e) {
// Found this on a website, but doesn't work
this.set('route.path', '/view-question');
}
}
window.customElements.define(MyView1.is, MyView1);
I don't know if it's any useful, but here are my imports in case you need to know.
<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../bower_components/paper-button/paper-button.html">
The fact is Polymer doesn't do that, some element (app-route which implement with Polymer) do that. The Polymer itself is the library that help you work with custom element easier.
This behavior done by JavaScript and History API. See how to use it on mdn. An application like this, dynamically rewriting the current page rather than loading entire new pages its called a single-page application (SPA).
Basically application like this have only one page (index.html). When you try to load from another path the server will cannot find it.
You can resolve this by config the server to serve every path you used with index.html. For development you can easily use polymer serve command from polymer-cli see here.
To link to another page you can done by many ways:
=> Wrap your element with <a>:
<a href='/another-page'>
<paper-button>...</paper-button>
</a>
=> Change route variable from app-location: in my-app.html
<app-location route='{{route}}'></app-location>
...
<paper-button on-click='changeRoute'>...</paper-button>
class MyApp extends Polymer.Element {
...
changeRoute () {
this.set('route.path', '/another-page')
}
...
}
If you want to do this in your file just import and use app-location.
=> Use History API
window.history.pushState({}, null, '/another-page');
// Notify to `app-location`
window.dispatchEvent(new CustomEvent('location-changed'))

Problems with obtaining the Firebase storage reference

I have a problem getting the storage reference even though I configured the firebase-app according to documentation. The firebase-app element is located in the index.html
<firebase-app name="name-of-the-app"
api-key="api_key"
auth-domain="name-of-the-app.firebaseapp.com"
database-url="https://name-of-the-app.firebaseio.com"
storage-bucket="name-of-the-app.appspot.com">
</firebase-app>
I am accessing the app reference in the subviews the following way:
<firebase-document id="office_document"
app-name="doctor-appointment-system"
path="/offices">
</firebase-document>
<script>
this.$.office_document.app.storage()
</script>
The code above is throwing the an error.
this.$.office_document.storage is not a function
The database counterpart works ok.
this.$.office_document.app.database()
The problem was that I didn't have firebase storage script imported in my index.html, where the app was initialized with firebase-app element.
Here is what my imports look like now:
<link rel="import" href="/bower_components/polymerfire/firebase-app.html">
<link rel="import" href="/bower_components/polymerfire/firebase-storage-script.html">
<link rel="import" href="/bower_components/polymerfire/firebase-document.html">

HTML import angular2 app and pass parameter

I want to use webcomponents and HTML import to import an angular2 module into another webapplication which do not use angular2. I know HTML import is only natively supported in few browsers but i will use the polymer framework to pollify other browsers.
I can import the angular app but i'm unable to pass parameters to the angular app from my web app that imports the angular app. I'm trying this:
<dom-module id="sale-stats">
<link rel="import" href="../bower_components/polymer/polymer.html">
<template>
<!-- contains my angular app bundled js files -->
<link rel="import" href="imports.html">
{{saleid}} <!-- this displays the saleid just to see that the parameter is passed to the webcomponent -->
<app-root saleid='{{saleid}}'>Loading... </app-root>
</template>
<script>
HTMLImports.whenReady(function () {
Polymer({
is: 'sale-stats',
properties: {
saleid: {
type: String,
value: '0'
}
},
});
});
</script>
</dom-module>
<script src="/Scripts/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="http://localhost:9600/salestats/index.html" />
<sale-stats saleid="1234567"></sale-stats>
How do i pass parameters to my angular app when using the angular app as a webcomponent that is imported into another app? Or is it just completely wrong to try and import an angular app as an webcomponent?
In order to polyfill HTML Imports, you just have to include HTMLImports.js which is available in the webcomponents.js repository. You can install it with bower (or npm):
bower install webcomponentsjs
Just include the polyfill before the <link> element:
<script src=".../bower_components/webcomponentsjs/HTMLImports.js"></script>
To wait for the imported file to be loaded, you can use the Promise, or instead wait for the standard onload event. For example:
<script src=".../bower_components/webcomponentsjs/HTMLImports.js"></script>
<link rel="import" href="imports.html" onload="run( 1234567 )">
Inside the imported HTML file:
<!-- contains my angular app bundled js files -->
<script>
function run ( id )
{
var app = document.createElement( 'app-root' )
app.setAttribute( 'saleid', id )
document.body.appendChild( app )
}
</script>
Notes: you can also place the onload callback function in the main document. Also, the import is synchronous on native implementation (Chrome and Opera); use async in <link> if you don't want to block the parsing.

Using third-party dependencies in polymer (pikadate)

I'm creating a polymer datepicker using pikaday. Sadly it seems like I got something wrong.
I'd like to import pikaday.js and pikaday.css the right way.
At first I had a simple script-tag below my closing dom-module-tag, like
</dom-module>
<script src="../../pikaday/pikaday.js"></script>
<script>
Polymer({
//....
This way, the datepicker was created as expected. But after reading this SO-Thread I was under the impression I was supposed to import the js-file like this:
<link rel="import" href="../../paper-input/paper-input-behavior.html">
<link rel="import" href="../../paper-input/paper-input-error.html">
<link rel="import" href="../../pikaday/pikaday.js">
//more imports....
But after "fixing" my import, the file pikaday.js seems not to be visible from inside my component:
Uncaught ReferenceError: Pikaday is not defined
Furthermore I'm confused about using external css. After reading this guide it seems like I was supposed to copy & paste the contents of the provided css-file into a my-datepicker-style.html and to import it into my template like this:
<dom-module id="my-datepicker">
<template>
<style include="my-datepicker-style"></style>
<style>
:host {
//more css
I'm confused about the need to copy & paste existing code.
Until ES6 imports are more common, you need some kind of workaround for referencing dependencies.
The problem with <script> tag is that when it appears multiple times, it will be processed multiple times. This is not true for <link rel="import">. Same href will be processed only once.
You cannot, however, import javascript directly. The trick is to create pikaday-import.html file with the script reference
<script src="../../pikaday/pikaday.js"></script>
You then import that in your element's html
<link rel="import" href="pikaday-import.html" />
<dom-module id="my-datepicker"></dom-module>
This is the technique for example the <marked-element> uses.
This way instances of <my-datepicker> load pickaday only once. Unfortunately, if there are other components which reference it, you could end up loading the dependency multiple times.

How to import core elements and paper elements in JSFiddle

How can I import core elements and paper elements in JSFiddle.
I'm importing polymer through those statements:
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.4.2/platform.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/polymer/0.4.2/polymer.js"></script>
How can import for example core-input or paper-input?
Yes from the polymer project site or I guess your cloudflare cdn if you know the location
<script src="http://www.polymer-project.org/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/paper-button/paper-button.html">
<link rel="import" href="http://www.polymer-project.org/components/core-header-panel/core-header-panel.html">
This is just for dev and not production.
If you goto polymer elements then choose your element and click on the button that says Get Element it will give you a popup with an import link.
Also you can get a link for all core or paper elements from here
A good alternative - still a work in progress - is https://ele.io/
Ele (call it “Ellie”) is a streamlined environment for exploring, experimenting with, and sharing reusable custom HTML elements made with Web Components.
To test a simple component written in Polymer 1.0 I use this snippet:
<link rel="import" href="https://raw.githubusercontent.com/Polymer/polymer/master/polymer.html">
<dom-module id="proto-element">
<template>
<span>I'm <b>proto-element</b>. Check out my prototype.</span>
</template>
</dom-module>
<script>
Polymer({
is: "proto-element",
ready: function() {
//...
}
});
</script>
<proto-element></proto-element>
http://jsfiddle.net/MartyIX/84b5sabw/

Categories

Resources