Jonathan
Jonathan

Reputation: 735

XML in Polymer template with iron-ajax - handle-as, adding XML DOM to template

I'm writing my first Polymer app, which should allow people to read Greek texts from the Bible. I'm trying to read an XML file to create a DOM, then use it in a template.

In <iron-ajax>, does handle-as="xml" work? This bug suggests that it might not: https://github.com/PolymerElements/iron-ajax/issues/53

The following code loads a file if I change handle-as="xml" to handle-as="text", but (obviously) the result is just a bunch of text with angle brackets, not an XML DOM. It does not work if I change it to handle-as="document":

<template>

  <iron-ajax auto
    url="https://raw.githubusercontent.com/biblicalhumanities/greek-new-testament/master/syntax-trees/nestle1904-lowfat/xml/04-john.xml" 
    handle-as="xml"   
    last-response="{{response}}"
    >
  </iron-ajax>

  [[response]]

</template>

See this Plunker:

https://plnkr.co/edit/ByMHcM7xciS2JkkF3MXI?p=preview

The above code is in content-el.html. It works if you change handle-as="xml" to handle-as="text".

Questions:

  1. Is my problem with handle-as="xml" due to the bug in https://github.com/PolymerElements/iron-ajax/issues/53, or am I thinking this wrong?
  2. I assume I could retrieve the text, parse it as XML, and put that result where [[response]] occurs in the template. How would I do that?

Upvotes: 1

Views: 1091

Answers (1)

tony19
tony19

Reputation: 138436

Here are the relevant parts of the MDN docs you need:

The XMLHttpRequest.responseXML property is [...] null if the request was unsuccessful, has not yet been sent, or if the retrieved data can't be correctly parsed as XML or HTML.

[...]

If the server doesn't specify the Content-Type header as "text/xml" or "application/xml", you can use XMLHttpRequest.overrideMimeType() to force XMLHttpRequest to parse it as XML anyway.

In the handler of the <iron-ajax>.response event, if we log the XHR's response (i.e., event.detail.response.xhr.responseXML), we see it's null, which indicates one of failure conditions mentioned in the MDN docs above. It's likely that the response body couldn't be parsed properly because of an unexpected Content-Type.

In your case, the server is responding with a Content-Type of text/plain despite the request header containing Accept: text/xml, which causes a parser error, leading to a null for responseXML.

enter image description here

We can fall back to the workaround indicated by the MDN docs to use XMLHttpRequest.overrideMimeType() to force the parsing of the contents as XML regardless of its Content-Type. This can be done in an <iron-ajax>.request event handler (fired before the request is sent):

<iron-ajax auto
  url="https://raw.githubusercontent.com/biblicalhumanities/greek-new-testament/master/syntax-trees/nestle1904-lowfat/xml/04-john.xml" 
  handle-as="document"
  headers='{"Accept": "text/xml"}'
  last-response="{{response}}"
  on-request="_onRequest"
  >
</iron-ajax>

// script
_onRequest: function(e) {
  const req = e.detail.request;
  req.xhr.overrideMimeType('text/xml');
}

codepen

Also see related post.

Upvotes: 1

Related Questions