Search code examples
javascriptpolymerweb-component

Dynamically Load HTML page using Polymer importHref


I'm writing a simple element that loads html files using Polymer 1.0's helper function importHref(). The page loads in, but instead of the html rendering to the page, I'm getting [object HTMLDocument].

When I log the successful callback, the imported page is wrapped in a #document object (not sure on the terminology here). But, the info is all there in the console.

So, my question is: How do I render the html to the page?

element:

<dom-module id="content-loader">

<template>
    <span>{{fileContent}}</span>
</template>

<script>

Polymer({

    is: "content-loader",

    properties: {
        filePath: {
            type: String
        }
    },

    ready: function() {
        this.loadFile();
    },

    loadFile: function() {
        var baseUrl;

        if (!window.location.origin)
        {
            baseUrl = window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '');
        }
        else
        {
            baseUrl = window.location.origin;
        }

        //import html document and assign to fileContent
        if(this.filePath)
        {
            this.importHref(baseUrl + this.filePath, function(file){
                this.fileContent = file.target.import;
                console.log(this.fileContent); //logs fine
            },
            function(error){
                console.log(error);
            });
        }
    }

});

</script>

in use:

<content-loader file-path="/app/general/contact.html"></content-loader>

Solution

  • <span>{{fileContent}}</span> will render fileContent cast to a String, which is why you see [object HTMLDocument] (which is what you get when you call toString() on a document Object).

    Just in general, Polymer won't let you bind to HTML or node content because it's a security risk.

    The fileContent you have is a document, which means it's a collection of DOM nodes. How you use that document depends on what the content is that you loaded. One way to render the nodes is to append fileContent.body onto your local DOM, like so:

    Polymer.dom(this.root).appendChild(this.fileContent.body);

    Here is a more complete example (http://jsbin.com/rafaso/edit?html,output):

    <content-loader file-path="polymer/bower.json"></content-loader>
    
    <dom-module id="content-loader">
    
      <template>
        <pre id="content"></pre>
      </template>
    
      <script>
    
        Polymer({
          is: "content-loader",
          properties: {
            filePath: {
              type: String,
              observer: 'loadFile'
            }
          },
    
          loadFile: function(path) {
            if (this.filePath) {
              console.log(this.filePath);
              var link = this.importHref(this.filePath, 
                function() {
                  Polymer.dom(this.$.content).appendChild(link.import.body);
                },
                function(){
                  console.log("error");
                }
              );
            }
          }
        });
    
      </script>
    </dom-module>