Search code examples
polymer-2.x

How to render html entity symbols in a dom-repeat?


I ask this questions because all existing solutions which are existing like:

for example are outdated and/or not working any longer.

I have a simple dom-repeat statement:

<template is="dom-repeat" items="[[items]]">
    <a target="_blank" href="[[item.url]]">[[item.label]]</a>
</template>

As you can see here im showing a list of urls. When the datasource now contains html entities:

this.push('items', {
    label: '&copy; Google 2018',
    url: 'http://www.google.de'
});

The entities wont render:

&copy; Google 2018

My <a> tags wont have any id's and I also dont know which datasource item has an html entity and which not. So how am I supposed to render html entities with Polymer version 2.5.0?


Solution

  • A solution is to assign each item in the dom-repeat a unique id, then set the innerHTML on that item after the render.

    In the following code (and this pen) I set an id with _assign(index). In the ready() method, I call Polymer.RenderStatus.afterNextRender to wait for all items to draw, then set the anchors' innerHTML's in the same manor using a querySelector on that id:

    <dom-module id="show-entity">
      <template>
        <style>
          :host {
            display: block;
          }
        </style>
        <template is="dom-repeat" items="[[items]]">
          <a target="_blank" id="[[_assign(index)]]" href="[[item.url]]"></a><br>
        </template>
      </template>
    
      <script>
        /**
         * `show-entity`
         * https://stackoverflow.com/questions/21060890/
         *
         * @customElement
         * @polymer
         * @demo demo/index.html
         */
        class ShowEntity extends Polymer.Element {
          static get is() { return 'show-entity'; }
          static get properties() {
            return {
              items: {
                type: Array,
                value: () => { return []; }
              }
            }
          }
          ready() {
            super.ready();
            this.items.push({
              label: '&copy; Google 2018',
              url: 'http://www.google.de'
            },{
              label: '&#167; Google 2018',
              url: 'http://www.google.de'
            });
    
    
            Polymer.RenderStatus.afterNextRender( this, () => {
              this.items.forEach((el, idx) => {
                let id = this._assign(idx);
                this.shadowRoot.querySelector('#'+id).innerHTML = el.label;
              });
            })
          }
    
          _assign(index) {
            return 'foo'+index;
          }
        }
    
        window.customElements.define(ShowEntity.is, ShowEntity);
      </script>
    </dom-module>
    

    Note that you must import polymer/lib/utils/render-status.html to use Polymer.RenderStatus.afterNextRender.