Polymer: unable to access dom-if content by id

Created on 7 Dec 2015  路  14Comments  路  Source: Polymer/polymer

In a custom element I want to access a span and append a child to it but all usual accessors give undefined:

<template>
    <template is="dom-if" if="[[condition]]" restamp>
        <span id="myspan"></span>
    </template>
</template>

 ready() {
   var a = this.$.myspan;                     //<------- is undefined
   var b = this.$$.myspan;                    //<------- is undefined
   var c = document.getElementById("myspan"); //<------- is undefined
   //UPDATE
   var d = this.$$("#myspan");                //<------- is undefined
}

Interesting that outside ready function (after a bit of time when all components are loaded) I can access it in a console via document.getElementById("myspan")... but I need a place in a code to append a child.

How to access a span in this case?

related: http://stackoverflow.com/questions/34138718/how-to-access-content-of-dom-if-inside-a-custom-element

question

Most helpful comment

this.$$ is no longer in Polymer 2.0.

this.shadowRoot.querySelector(...) is the way to go:
https://www.polymer-project.org/2.0/docs/devguide/dom-template#node-finding

All 14 comments

https://www.polymer-project.org/1.0/docs/devguide/local-dom.html#node-finding

Note: Nodes created dynamically using data binding (including those in dom-repeat and dom-if templates) are not added to the this.$ hash. The hash includes only statically created local DOM nodes (that is, the nodes defined in the element鈥檚 outermost template).

For locating dynamically-created nodes in your element鈥檚 local DOM, use the $$ method:
this.$$(selector)
$$ returns the first node in the local DOM that matches selector.

Edit: So what should work is this.$$('#span') or this.$$('span').

@JeremybellEU, this.$$("#myspan") is also undefined

is the condition met at ready time?

condition is a function:

_eq(a, b) {
    return a === b;
 }

and in the ready function I already have defined ''a'' and ''b'' values.

not sure if this is what you was asking...

did you verify that your <span> is being stamped before trying to access it?

emm.. no, how to verify that?

The template helpers (dom-if, dom-repeat, dom-bind) fire a dom-change event when they create or remove nodes.

https://www.polymer-project.org/1.0/docs/devguide/templates.html#dom-change

This is a little confusing (and could be clarified better in the docs), but the dom-if is just another element in your element's local DOM. When ready is called on your custom element, the if value has been set on your dom-if, but it hasn't had a chance to instantiate its DOM yet.

For more discussion on this, see this doc bug:

https://github.com/Polymer/docs/issues/1456

@arthurevans, that is helpfulll. one question though:
does render() method on dom-if element guarantees that dom-if children are ready?

DOM changes are async. One way around this is to wait for the dom-change event or wrap your call with this.async() so it waits for the next frame. At that point the DOM will be stamped.

For those who encounter same difficulties :

this.$$('#cssId')

works for me.

DOM changes are async. One way around this is to wait for the dom-change event or wrap your call with this.async() so it waits for the next frame. At that point the DOM will be stamped.
馃憤 1

@ebidel
I wrapped my call in async without giving it a time and the selector this.$$('myId') still returned null after the if variable turned truthy in dom-if

@marko911 you need to use # when querying by id, like this:
this.$$('#myId')

this.$$ is no longer in Polymer 2.0.

this.shadowRoot.querySelector(...) is the way to go:
https://www.polymer-project.org/2.0/docs/devguide/dom-template#node-finding

"This.$" works if you call super.ready() before accessing the DOM element in ready().

Was this page helpful?
0 / 5 - 0 ratings