How to Access Member Functions in Polymer Elements

Share this article

This article is part of a web dev tech series from Microsoft. Thank you for supporting the partners who make SitePoint possible.

image 1- polymer

I’m working on a silly Polymer project right now, which parses a Pokémon database and returns a picture of a Pokémon, then speaks the creature’s name over your speakers. Here’s the source code for my project.

It’s my first time using Polymer, and I’m certainly getting snagged in a few spots. Most recently, it was trying to return member functions of a Polymer object that I created. Took me forever to figure this out, so I wanted to share it with you in this tutorial.

Sidenote: you can also search for my more detailed write-up on Web Components here.

The Wrong Way

I have a Web Component which looks like this:

<x -radial-buttons id="radial-button-template"></x>

If I try to access it by its ID…

var  temp = document.querySelector("#radial-button-template");
// returns <x -radial-buttons id="radial-button-template"></x>

I cannot access any of the functions inside it. They return undefined. So if I tried this:

var  temp = document.querySelector("#radial-button-template");
temp.getFirstElement  // returns undefined

Why Is This Happening?

This is due to the Shadow DOM’s encapsulation. It is both a gift and a curse. In this case, I am accessing the element, and not the shadowRoot, which will expose the public methods attached to the Shadow DOM object.

In the next step, you’ll see how I can access the member functions in my custom element, as well as how I can return nodes that lie even deeper in my web component.

Rob Dobson of Google’s Polymer team explains this well in this blog post. Eric Bidleman goes into even more detail in his advanced Shadow DOM article. I strongly suggest taking the time to read these over to better understand how this version of the DOM works.

One Way of Doing It

var btn = document.querySelector("x-radial-buttons");

Notice that I’m not using the hash symbol (#) to access the element, as though it were an ID. Instead, you need to simply refer to the name of the polymer-element itself:

document.querySelector("x-radial-buttons");

so now I can write:

var temp = document.querySelector("x-radial-buttons");
// ALSO returns <x-radial-buttons id="radial-button-template"></x-radial-buttons>

Now I can access all of the members like this:

var temp = document.querySelector("x-radial-buttons");
temp.getFirstElement
// returns <paper-radio-button label="English-US" id="paper_radio_btn_en-US" on-click="{{ changeAccentUS }}" role="radio" tabindex="0" aria-checked="false" aria-label="English-US"></paper-radio-button>

Therefore, I suggest not assigning an ID to your polymer-element at all. As Rob made clear in the comments below, you can query for a custom element however you want (via ID, class, attr, or element name) and get the same thing. Here’s his example: http://jsbin.com/qikaya/2/edit

Another way of doing it…

You can also grab the ID of a polymer element and access the member functions.

This is done by using a ‘polymer-ready’ event. As the docs describe it:

Polymer parses element definitions and handles their upgrade asynchronously. If you prematurely fetch the element from the DOM before it has a chance to upgrade, you’ll be working with a plain HTML element, instead of your custom element.

And this is exactly the issue I was running into earlier. I was trying to grab functions within my polymer-element before Polymer had a chance to upgrade it. Here’s an example:

<head>
  <link rel="import" href="path/to/x-foo.html">
</head>
<body>
  <x-foo></x-foo>
  <script>
    window.addEventListener('polymer-ready', function(e) {
      var xFoo = document.querySelector('x-foo');
      xFoo.barProperty = 'baz';
    });
  </script>
</body>

In conclusion, as long as you wrap the functions you are trying to call in the polymer-ready event, you should be good to go, and can call functions from your polymer-element.

How I Use It

(function (PokémonApp) {

// Grab inputs and button for speech-to-text
var form                 = document.querySelector('#player-form'),
    input                = document.querySelector('#player-input'),
    playerElement        = document.querySelector('#player-element'),
    xPokémon             = document.querySelector('#x-Pokémon'),
    btnChangeAccent      = document.querySelector('#btn-change-accent'),
    radialButtonTemplate = document.querySelector("#radial-button-template"),
  	playerAccent     = playerElement.getAttribute("accent");

// Take text from input & set it as the text that the speaker will say.
// Set the name of the Pokémon, which angular will then grab from the Pokémon DB 
input.addEventListener('input', function (e) {
	playerElement.setAttribute('text', input.value);
	xPokémon.name = input.value;
});


// Say the text when button is pressed
form.addEventListener('submit', function (e) {
	e.preventDefault();
	playerElement.speak();
	var btn = document.querySelector("x-radial-buttons");
	btn.getFirstElement();
});
<header>
<h1>article header h1</h1>
<p>This web app takes advantage of Web Components and Polymer to enable new HTML features in the browser.</p>
<p>
	In this particular case, we are using <a href="https://github.com/passy/x-Pokémon">
	the x-Pokémon web component </a> to pull the images from a database, as well as the 
	<a href="http://zenorocha.github.io/voice-elements/">voice-elements web component</a> to speak the name of the Pokémon we entered.							
</p>
<h2>Change the accent</h2>
<x-radial-buttons id="radial-button-template"></x-radial-buttons>
</header>

More JavaScript Learning

It might surprise you a bit, but Microsoft has a bunch of free learning on many open source JavaScript topics and we’re on a mission to create a lot more with Microsoft Edge coming.

Here’s our team’s broader learning series on HTML, CSS, and JS:

This article is part of a web dev tech series from Microsoft. We’re excited to share Microsoft Edge and the new EdgeHTML rendering engine with you. Get free virtual machines or test remotely on your Mac, iOS, Android, or Windows device at http://dev.modern.ie/

Frequently Asked Questions about Accessing Member Functions in Polymer Elements

What are Polymer Elements and how do they function?

Polymer Elements are reusable components created using Polymer Library, a lightweight sugaring layer on top of the Web Components APIs. They are designed to make it easier and more efficient to build your own custom HTML elements. You can think of them as building blocks that you can use to create a full web application. Each Polymer Element has its own functionality and can have its own style and content, separate from the main document.

How can I access member functions in Polymer Elements?

To access member functions in Polymer Elements, you can use the ‘this’ keyword. For instance, if you have a member function named ‘myFunction’, you can access it by using ‘this.myFunction()’. It’s important to note that the ‘this’ keyword refers to the Polymer element instance.

Can I use Polymer Elements with other JavaScript libraries or frameworks?

Yes, Polymer Elements can be used with any JavaScript library or framework that can work with HTML. They are just like any other HTML elements, so they can be manipulated using JavaScript and can be used in conjunction with other libraries or frameworks.

How can I create a custom Polymer Element?

To create a custom Polymer Element, you need to define a class that extends Polymer.Element and then call customElements.define() with the name of your element and the class that implements it. The name of your element must contain a dash (-), to ensure it’s valid and won’t conflict with existing or future HTML elements.

How can I add properties to my Polymer Element?

You can add properties to your Polymer Element by adding a static properties getter to your element’s class. The properties getter should return an object that defines the property’s name, type, value, and other optional configurations.

How can I listen for and respond to events in Polymer Elements?

Polymer provides an automatic node finding feature for automatically locating dynamically-created nodes in your element’s local DOM. You can add an event listener to these nodes by adding an attribute to the node in your element’s template.

How can I use data binding in Polymer Elements?

Polymer supports both one-way and two-way data binding. To bind data, you can use the double curly braces {{}} for one-way data binding and square brackets [] for two-way data binding.

How can I style my Polymer Elements?

You can style your Polymer Elements by using standard CSS inside a style tag in your element’s template. Polymer also provides a set of custom CSS properties for styling the shadow DOM.

Can I use Polymer Elements in all browsers?

Polymer Elements are built on top of the Web Components APIs, which are not supported in all browsers. However, Polymer provides a set of polyfills that emulate the Web Components APIs in browsers that don’t support them natively.

How can I test my Polymer Elements?

Polymer provides a set of tools and libraries for testing your elements. You can use the Polymer test utility to create a test environment for your elements, and the web-component-tester library to run your tests.

David VoylesDavid Voyles
View Author

Dave Voyles is a Technical Evangelist for Microsoft. He spends a lot of time writing games, writing about games, and writing about how to write games for the game dev community, Read his blog or follow him on Twitter.

mdnpolymer
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week