Fetch API Featured Image
UI Development

Fetch API

For over a decade we have been using XMLHttpRequest to attain asynchronous requests in JavaScript. XHR is extremely useful but has its own disadvantages. XHR manages by interacting with one object, and state is tracked using events. Event-based model does’t play well with JavaScript’s recent specialize in Promise and generator-based asynchronous programming.

The Fetch API provides an interface for fetching resources across the networks. it’s familiar to XMLHttpRequest, but the new API provides a more powerful and versatile feature set.

The fetch() method is modern and versatile. Fetch API provides an improved alternative that may be easily employed by other technologies like ServiceWorkers. Fetch introduces 3 interfaces. These are HeadersRequest and Response. They map on to the underlying HTTP concepts but have certain visibility filters in situ for privacy and security reasons, like supporting CORS rules and ensuring cookies aren’t readable by third parties. it’s well supported by all modern browsers, but not supported by some old browsers (can be polyfilled).

Using fetch

Fetch API provides fetch method defined in window object, which returns a Promise that you simply can simply use can to retrieve the response of the request.

The basic syntax is:

fetch() takes two arguments. First one is resource URL and second parameter options object which is optional. Without options, that’s a simple GET request, downloading the contents of the url.

Here is the list of fetch options with their default values (alternatives in comments):

  • method: “GET” // POST, PUT, DELETE, etc.
  • headers: Headers {
    // The content type header is typical auto-set depend on the request body
    “Content-Type”: “application/json”
    }
  • body: undefined // FormData, string, Blob, BufferSource or URLSearchParams
  • referrer: “about:client” // or “” to send no Referrer header or same-origin URL
  • referrerPolicy: “no-referrer-when-downgrade”, // no-referrer, same-origin, origin, strict-origin, origin-when-cross-origin, strict-origin-when-cross-origin, or unsafe-url.
  • mode: “cors” // same-origin, no-cors
  • credentials: “same-origin” // omit, include
  • cache: “default” // no-store, reload, no-cache, force-cache, only-if-cached
  • redirect: “follow” // manual, error
  • integrity: “” // a hash, like “sha256-BpfBw7ivV8q2jLiT13fxDYAe22nFSE=”
  • keepalive: false // true
  • signal: undefined, // AbortController to abort request

 

Browser will execute fetch method immediately and returns a promise.

Getting a response from fetch is a two stage processes.

First promise returned by fetch will resolves with an object of response class as soon as the server responds with headers. At this stage we are able to check HTTP status if it is successful or not, but don’t have the body yet.

If you inspect the response in your browser’s console, you must see a Response object with several properties.

Screenshot of response in your browser’s console.

Second, to extract the body content from the response we need to use Body mixin methods, which is implemented by Request and Response object.

Body mixin has multiple methods to extract different types of body contents.

Methods/Properties Description Type
text() Read the response and return as text string
json() Read the response and parse the result as JSON string
formData()  Return the response as FormData object FormData
blob() Return the response as Blob (binary data with type), Blob/File
arrayBuffer() Return the response as ArrayBuffer (low-level representation of binary data) ArrayBuffer
body  body is a ReadableStream object, it allows you to read the body chunk-by-chunk. ReadableStream

Note: We can use body-reading method only once. If we’ve already got the response with response.text(), then response.json() won’t work again, because the body content has already been processed.

The most common response properties you’ll use are:

  • response.status — An integer (default value 200) containing the response status code.
  • response.statusText — A string (default value “OK”), which corresponds to the HTTP status code message.
  • response.ok — seen in use above, this can be a shorthand for checking that status within range 200-299 inclusive. This returns a Boolean.

Error handling

Handling errors with Fetch isn’t straightforward processes as handling in success messages. As fetch() returns a promise, we are able to use catch method of the promise to intercept an error which occur during the execution of the request.

Promise returned from fetch wont rejects on HTTP error status even it’s 404 and 500 status code. Instead it’ll resolve normally (with ok status set to false), and it’ll reject on network failure or if anything prevented the request from completing.

Canceling fetch request

When fetch was introduced, there are two issue many JavaScript lovers used to comment.

  • There is no way to abort a request once opened.
  • There is no request timeout for fetch.

 

Due to continuous improvements in JavaScript ecosystem, new features AbortController and AbortSignal are introduced, a generic API to notify abort events. This solves the problem of aborting a request.

Still there is no inbuilt feature for fetch() to set request timeout but we can make use of setTimeout() and above abort functionality to solve the request timeout functionality. 

But setTimeout() will trigger abort() even fetch already returned. Handily, event fetch already returned, calling abort() won’t cause any error. When abort signal triggered, fetch will reject the promise with an DOMException named ‘AbortError’. Using this we differentiate the generic errors with request timeout errors.

We can improvise above abort process using Promise.race().

Simple custom fetch wrapper

We can build our own custom fetch wrapper by leveraging about code snippets. This can be used in small applications as an alternative for axios or any other sophisticated libraries. A simple custom fetch wrapper looks as shown below. It can be improvised based on our needs.

We can use this typical library as shown below.

GET

POST

This syntax will be similar for other methods provided. 

Conclusion

Building own fetch wrapper around fetch and upgrading it as per our needs can definitely change your thoughts of using sophisticated libraries like JQuery, Axios, etc. Fetch is still evolving, this is an experimental API that should not be used in production code.

We can contribute to the evolution of this API by participating in discussion on the WHATWG and the issues in the Fetch and ServiceWorker specifications.

References

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

https://javascript.info/fetch-api

https://davidwalsh.name/fetch

https://css-tricks.com/using-fetch/

 

About The Author