New Ajax Fetching


Out with the old in with the new? While lazily googling for a simple ajax one liner for a toy project I kept getting jquery results. Thanks for that. Actually had to remember the "xmlhttprequest" garble which turned up the default mdn page which gave me the four liner I was looking for.

var oReq = new XMLHttpRequest();
oReq.addEventListener('load', load);'GET', 'cardlist.txt');

This, of course, works fine provided the resource is accessible to you. But this is the old. And it's "unsafe". Or at least, for full backwards compatibility you'll need more. Way more. I still have a 7k ajax script on this site somewhere and even my recent short cut and paste example is "huge". Relatively speaking at least, even to the above.

So what is the new? Well, it's fetch. It doesn't even come with a global namespace; it's just a global function. Like atob the browser will expose this if it supports it. I'm not sure whether I would have gone without a namespace but I'm sure the powers that be thought this one through... Ahem, moving on.

This is the same ajax example from above using the Fetch api:

fetch('cardlist.txt').then(r => r.text()).then(load);
// dont forget error handlers!

A proper one liner, even if it's cheating (insofar that with chaining and arrow functions the "line" of what constitutes a single line is a little blurry in JS). It's actually quite elegant, especially if you're a sucker for that Promise API. I'm not buying it but that's a different story.

Fetch actually goes a lot further than this. There's a whole API to support more recent technologies like loading images as Blobs and thorough header manipulation. And of course wrapped in some Promise sugar rather than the browser event model, which if nothing else at least should synchronize the API between browser and non-browser platforms. That's a win by my book regardless of how you feel about promises.

Oh yeah how does the one liner work? It's really just the promise sugar to explain there; The call to fetch tries to load the given resource and returns you a promise. When the promise resolves (without rejecting) you get a response object. This is an object that refers to the response but without actually exposing it. Instead it exposes some meta information and content generating methods, like response.text() and response.blob(). A call to them first returns a new promise which resolves when the browser is ready to deliver you the content (text, blob, whatever it is you requested). Only when that resolves do you actually have the content.

You can chain promises by returning a promise in a then and chaining of, like the example above. If you're still confused you should search for a promise intro online :)