skip to Main Content

I am making an AJAX get request which returns an XML object containing a fully-qualified SVG. In the browser’s inspector I can see the response header indicates it is ‘application/xml’, and I can see the response itself: <svg> .... </svg>, correctly structured with namespace headers etc.

I then try to render the object within a and it is rendering [object Object] instead of the content itself. If the AJAX call populated the var ‘src’, I write:

element = document.getElementById('myDiv');
element.innerHTML = src;

I have looked at various other articles about this, e.g. using DOMParser, but the best I get is that it renders something like [object XMLElement] etc. Very frustating.

Is there a simple way to just have the actual SVG put between the tags so it renders the graphics therein?

3

Answers


  1. Chosen as BEST ANSWER

    So the entire problem was that in my $.ajax call, I had the parameter dataType: 'application/xml'. By changing the value to just 'xml' or even removing it and letting it guess, then my response was a valid XMLDocument.

    By having the incorrect value, it created an empty Object which was the root of all my problems.

    Thanks to everyone for their assistance regardless.


  2. All you need is a native JavaScript Web Component <load-file src="">

    customElements.define("load-file", class extends HTMLElement {
      // declare default connectedCallback as sync so await can be used
      async connectedCallback(
        // call connectedCallback with parameter to *replace* SVG (of <load-file> persists)
        src = this.getAttribute("src"),
        // attach a shadowRoot if none exists (prevents displaying error when moving Nodes)
        // declare as parameter to save 4 Bytes: 'let '
        shadowRoot = this.shadowRoot || this.attachShadow({mode:"open"})
      ) {
          // load SVG file from src="" async, parse to text, add to shadowRoot.innerHTML
        shadowRoot.innerHTML = await (await fetch(src)).text()
    
        // append optional <tag [shadowRoot]> Elements from inside <load-svg> after parsed <svg>
        shadowRoot.append(...this.querySelectorAll("[shadowRoot]"))
    
        // if "replaceWith" attribute 
        // then replace <load-svg> with loaded content <load-svg>
        // childNodes instead of children to include #textNodes also
        this.hasAttribute("replaceWith") && this.replaceWith(...shadowRoot.childNodes)
      }
    })
    <load-file src="//load-file.github.io/heart.svg"></load-file>

    Full documentation: https://dev.to/dannyengelman/load-file-web-component-add-external-content-to-the-dom-1nd

    Login or Signup to reply.
  3. You should probably get the rootElement.outerHTML from the object, because it is a XML document that is returned.

    The example should show a blue square. I use a data URL for the request, but that can be replaced by a normal URL.

    $.ajax({
      type: "GET",
      url: "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/Pgo8c3ZnIHZpZXdCb3g9IjAgMCAxMCAxMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8cmVjdCB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIGZpbGw9ImJsdWUiLz4KPC9zdmc+Cgo=",
      dataType: "xml",
      success: function(xml) {
        $('#myDiv').html(xml.rootElement.outerHTML);
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="myDiv" style="width: 200px"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search