Better form processing with fetch()

I finally put the time in and wrestled with the JavaScript fetch() API until I understood it well.

Here’s the script.

I also learned how to use the FormData constructor to easily grab all the values from an HTML form on submission. Same script. This is something I used to do with jQuery’s $( this ).serialize().

More about using fetch()

From this:

  1. “The fetch() method takes the path to a resource as input.
  2. “The method returns a promise that resolves to the Response of that request.”

Refer to the brief code examples in my earlier post. You’ll see that the .then() statements following the promise are different depending on the expected response data type, e.g. text or JSON.

“Evaluating the success of responses is particularly important when using fetch because bad responses (like 404s) still resolve.” This means that any response at all is a valid response to the fetch() method. The example below looks fine — until you realize that.

.then(function(response) {
   // do stuff with the response
.catch(function(error) {
   console.log('Looks like there was a problem: \n', error);

So what we really need in the .then() statement is this:

.then(function(response) {
   if (!response.ok) {
      throw Error(response.statusText);
   // do stuff with the response

The Response includes response.ok, response.status, response.statusText, etc. Use response.status, for example, to see if you got a 404 or similar error (more info).

The code following the sentence (here) “This code will be cleaner and easier to understand if it’s abstracted into functions” is very helpful. It demonstrates promise chaining and is explained below the code.

The same article contains examples for fetching images and fetching text.

We can add a method such as POST or HEAD (to get metadata) when requesting a resource with fetch (the default method is GET):

fetch( 'examples/words.txt', { method: 'HEAD'} )

Custom headers can be added in the same way (using the init parameter with headers: instead of method:).

Cross-origin requests

These can really mess up your day, as I learned one time when trying to use two APIs together in one web app. Cautions are explained near the end of the resource. It describes how to use no-cors mode with fetch.

  1. Fetch supports Cross Origin Resource Sharing (CORS).
  2. Testing generally requires running a local server.
  3. Note that although fetch does not require HTTPS, service workers do, and so using fetch in a service worker requires HTTPS. Local servers are exempt from this.

If you are using fetch without a service worker, you can use HTTP.

Fetch API: better than AJAX?

“A Promise-based mechanism for programmatically making web requests in the browser.” Replaces most uses of XMLHttpRequest in traditional web applications.

See more links at the end of this post.

Example 1 (run in console):

fetch('').then(response => {
   return response.text();
}).then(text => {

Example 2 (run in console with animals.json file in same dir as the currently open page):

fetch('animals.json').then(response => {
   return response.json();
}).then(json => {

Each of the examples returns the full contents of the file.

Some good stuff:

  • Working with the Fetch API — this is really clear, step by step, complete (from Google Developers; part of the PWAs workshop, but this can stand alone)
  • Slides that provide an overview of fetch()
  • Introduction to fetch() (also from Google Developers)
  • A window.fetch JavaScript polyfill (on GitHub): “Chrome and Firefox both implement the window.fetch function natively, [so] no code from this project actually takes any effect in these browsers.”