Using querySelector to find nested elements inside a Polymer template returns null

javascript, polymer, shadow-dom

Solution

document.querySelector('paper-tabs');

doesn't find the paper-tabs element, because it is hidden inside the shadow DOM of the tab-list element.

You can simply give paper-tabs an id, say tabs, and access it like so

this.$.tabs

(See http://www.polymer-project.org/docs/polymer/polymer.html#automatic-node-finding.)

There is also the option to access the shadow DOM directly

this.shadowRoot.querySelector('paper-tabs');

If you only want to listen for changes on the paper-tabs selection, you can use a change watcher:

<paper-tabs selected="{{currentTab}}">

Polymer('tab-list', {
  currentTab: 'all',
  currentTabChanged: function() {
    console.log(this.currentTab);
  }
});

(See http://www.polymer-project.org/docs/polymer/polymer.html#change-watchers)

Problem

I'm trying to use paper-tabs inside new element (tabs-list) but after print tabs I can't use querySelector to change selected one. Element code (without style): ``` <link rel="import" href="../components/polymer/polymer.html"> <link rel="import" href="../sprint-service/sprint-service.html"> <link rel="import" href="../components/paper-tabs/paper-tabs.html"> <polymer-element name="tab-list" attributes="show"> <template> <sprint-service id="service" sprints="{{sprints}}"></sprint-service> <paper-tabs selected="all" valueattr="name" self-end> <paper-tab name="all">ALL</paper-tab> <template repeat="{{sprint in sprints}}"> <paper-tab name="{{sprint.id}}">{{sprint.id}}</paper-tab> </template> </paper-tabs> </template> <script> Polymer('tab-list', { ready: function() { var tabs = document.querySelector('paper-tabs'); tabs.addEventListener('core-select', function() { list.show = tabs.selected; }) } }); </script> </polymer-element> ``` Index.html code (whitout style): ``` <!doctype html> <html> <head> <title>unquote</title> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <script src="../components/platform-dev/platform.js"></script> <link rel="import" href="../components/font-roboto/roboto.html"> <link rel="import" href="../components/core-header-panel/core-header-panel.html"> <link rel="import" href="../components/core-toolbar/core-toolbar.html"> <link rel="import" href="tab-list.html"> <link rel="import" href="post-list.html"> </head> <body unresolved touch-action="auto"> <core-header-panel> <core-toolbar> <tab-list></tab-list> </core-toolbar> <div class="container" layout vertical center> <post-list show="all"></post-list> </div> </core-header-panel> <script> var list = document.querySelector('post-list'); </script> </body> </html> ``` But ``` querySelector('paper-tabs') = *null* ``` I've tried to put the `eventListener` in index.html but I have the same problem. can anyone tell me where the problem is? Thank you very much!

Original source