How to: Use Polymer Webcomponents in Angular2

15

This post explain how to use a polymer webcomponent in an Angular2 app. We use the google maps component as an example.
For instructions on the demo app, see the bottom of this post.
The files of the demo application: demoApp

Getting started
Open the files of the demo app in your favorite editor and get started! We start of with an app that if you run it just displays hello world in the browser
helloworld.

To use polymer we need to add the polymer webcomponent references in the index.html
script1

When using polymer in Angular2 you need to fully enable shadowDOM. This will allow us to use angular data binding on the polymer element
Add this at after the scripts which import the libraries (and before the Angular2 script)

script2

We want to use the google map webcomponent so we import it to the index html, below the polymer script
script3first

Now we go to app.ts, where you will see the template, this is the template of the component.
Replace the “Hello world” with the google map webcomponent and use the coordinates of AMIS for the center.
component1

firstMap
It looks a bit dull though, lets add a marker to the map to show the exact location of AMIS!

For this we need to add the google marker webcomponent to index.html. We can add it below the google map marker that we already imported.
script3

Now add the marker with the same longitude and latitude into the google map component in our app.ts.
We will set the title of the marker to AMIS. So if we hover on the marker, it will show us AMIS.
component2
mapWithMarker

Data binding
Pretty neat right! But didn’t I say we can use data binding? So lets do that!
Change the template to use data binding for the latitude, longitude and title.
componentWithBinding

Set the default latitude, longitude and title in the constructor of the class of our angular component.

class GoogleMaps {  
 lat:string;
 long:string;
 title:string;
 
 constructor(){
     this.lat="52.0355031"
     this.long="5.0978835"
     this.title="AMIS";
 }   
}

Handling events

Data binding makes it way easier to change the values by for example clicking on a button
In the next steps we will make a button that changes the coordinates from AMIS to San Fransisco.
Of course, since we are using polymer webcomponents anyway, let’s use the paper button for that.
Go to the index.html and import the polymer paper-button.

script4

Add the button to the template in app.ts
componentWithButton

Notice we use the angular2 event binding by using (click)=”switch()”
Now add a switch() function to the class.
When we click the button and we are watching the location of AMIS we want to switch to San Fransisco and vice versa.

class GoogleMaps {
 lat:string;
 long:string;
 title:string;
 
 constructor(){
     this.lat="52.0355031"
     this.long="5.0978835"
     this.title="AMIS";
 }
 
 switch(){ 
     if(this.title=="AMIS"){   
        this.lat="37.779"
        this.long="-122.3892"
        this.title="San Fransisco!";}
     else{       
        this.lat="52.0355031"
        this.long="5.0978835"
        this.title="AMIS";
     }
 }

switchToSF
That’s it! We can now switch between places by pressing the button.

If you want your map to be more interactive, for example: people should be able to click the marker. We can bind the events of the polymer component. When we look at the documentation of the Google Map Component, we can see we have to set click-event to true to be able to handle events. Also there is a google-map-marker-click event that we can use.

We add a new function to our class to handle our marker event. For now it will just call the switch function.

class GoogleMaps {
 lat:string;
 long:string;
 title:string;
 
 constructor(){
     this.lat="52.0355031"
     this.long="5.0978835"
     this.title="AMIS";
 }

 clickedMarker(){
     this.switch();
 }
 
 switch(){ 
     if(this.title=="AMIS"){   
        this.lat="37.779"
        this.long="-122.3892"
        this.title="San Fransisco!";}
     else{       
        this.lat="52.0355031"
        this.long="5.0978835"
        this.title="AMIS";
     }
 }

In the google-map-marker component we can bind the event from the marker to this function by adding it to the template and setting click events to true.

clickedMarker

That’s how easy it is!
We now know how to use polymer webcomponents and their custom events in our angular2 application!

Demo app instructions

The demo app requires typescript, bower and npm.
The demo file has two projects:

  • helloWorldApp: starting point if you want to follow this tutorial
  • finishedApp: app with the google map polymer component already implemented

To run an app go to the folder (e.g. helloWorldApp) with the command line terminal.
The first time you have to install the dependencies with npm install and bower install.
To compile the app use: tsc (or tsc -w to keep watching)
To run the app use: npm run serve

Sources:
The files of the demo application: demoApp
Polymer google webcomponents
Polymer GoogleMaps documentation
Angular2 quickstart
Polymer

About Author

Cindy studied Software Engineering in Amsterdam. After university she starting working as an ADF developer at AMIS. Then webdevelopment happened and has since been the main focus. When not coding she is stopping balls as a goalkeeper.

15 Comments

  1. dharmalingam on

    How to integrate custom polymer components into Angular 2 application

  2. Dileep Keeppalli on

    Hi Cindey. I want to use a polymer component in my Ionic-2 application. and the component I have added as a node_module dependency instead of bower

    I am getting an error that 404 of xyz.html

  3. I was having a problem with page rendering in IE and Firefox, polymer elements were rendering in the wrong positions. I switched to use webcomponents.min.js instead of webcomponents-lite.min.js. That fixed the rendering problem, but now the paper-dialog element will not open on paper-button click. Has anyone faced similar issues??

  4. Hi Cindy; the link to appDemo files not working. Can you fix it? please

  5. Hi,

    In your article above you import Polymer and Polymer elements into the index page.
    Did you experiment with importing Polymer elements inside of an Angular2 component?
    It is not efficient to import all elements on page load, so it would be better to be able to lazy load them when needed.
    Especially if the elements are only used on one of the pages, but not on the others.

    Furthermore this is really interesting.
    I personally prefer Polymer, but at work we now use Angular2.
    Would be awesome to import a paper scroll header panel for example in Angular2.

    Great article,
    Thanks!

    • Cindy Berghuizen on

      I have not experimented with it yet. I used this mostly because the googlemap component of ng2 is not extended enough. Lazy loading would be better since these are two heavy frameworks to work with. Even better when material design 2 is more to the level of angular material design 1 to use for the design :).

  6. Hi Cindy,

    Excellent article and easy to follow. I am facing one issue though , if I refresh the page or go to another router link (another page template & component) and come back the marker vanishes. Am I doing something wrong here ?

    • Cindy Berghuizen on

      Thank you!
      Does the refresh issue also happen with the demo? And which browser are you using?

  7. Hi Cindy,
    the missing attributes for the latitude and longitude was the perfect hint!
    Using [attr.latitude]=”lat” [attr.longitude]=”long” will set the attributes and your demo is running in safari and firefox also.

    Great Blog, thank you again.

  8. Fredrik Borgström on

    Actually, this page itself is not displaying well in Firefox. All the images with code are tiny and illegible.

    • Cindy Berghuizen on

      Hi Fredrik,

      I noticed some images were tiny in IE as well. It seems to be fixed now.
      Also, there is a link to a zip file with the app you can download as well at the bottom of the page.

  9. This is what I was looking for. Thank you.
    But unfortunately catching the click events from the Web-Component, to switch places, is not working in Safari and Firefox.

    Any Idea to solve this?

    • Cindy Berghuizen on

      Hi,

      The click event does work you can check with a console.log inside the switch(), but when you check the sourcecode in firefox the latitude and longitude attributes in the element are missing. It seems it is a bug with databinding in Angular2 for firefox as can be found here and here.

      Also checking this it seems a good idea to update the es6-shim version to the latest, and add the polyfill for safari. (It does NOT solve the problem for firefox though, haven’t checked for safari)