A better way to use fetch api in Javascript
Tags: javascript, webdev, fetch, react
Published: 2020-07-06 06:08:49

I have a kind of love-hate relationship with JavaScript. Nonetheless, it has always intrigued me. I have been working on it for the last 3 years now, watching all the design patterns and learning new ones each day.

What makes a design pattern? How it all starts and how do people start to code something in a specific manner? Facing a new challenge while trying to make something scalable. Yes, that’s the first thing that makes us think about implementation and after that most of the time, we find an already existing way to go about the problem.
This is going to be something similar.

Let’s understand how we generally write a fetch call in javascript.

{% gist https://gist.github.com/mrinalraj/0b4256ed82130f73cae6d14383a6246e.js %}

* [**Body.arrayBuffer()**](https://developer.mozilla.org/en-US/docs/Web/API/Body/arrayBuffer)

* [**Body.blob()**](https://developer.mozilla.org/en-US/docs/Web/API/Body/blob)

* [**Body.formData()**](https://developer.mozilla.org/en-US/docs/Web/API/Body/formData)

* [**Body.json()**](https://developer.mozilla.org/en-US/docs/Web/API/Body/json)

* [**Body.text()**](https://developer.mozilla.org/en-US/docs/Web/API/Body/text)

Each of these function again returns a promise, which resolves to the type of data related to each of the functions.

In a real-world working project, there are numerous fetch calls, and every time if we start writing the above syntax we will simply end up writing so much of boilerplate codes.

> _As it is said in programming world. Never repeat yourself._

Let’s try to write a wrapper to make `GET` request. This wrapper function will help us keep the headers always same for all the requests and also make sure to keep the base `API_URL` consistent throughout the app.

{% gist https://gist.github.com/mrinalraj/b5cbafbb3cee28d4bb2df57942426911.js %}

Here the wrapper itself returns a `promise`, so we achieved some of the cases that need not be repeated, but I am still not satisfied with writing all the `try/catch` blocks.

This case reminds me of the syntax used in `golang`, which goes something like following.

    err, res := myFunction()

Here either `err` or `res` has a null value, depending on if there is an error. We will try and implement a RequestBuilder function that exposes a similar function that returns an array in the structure of `[error, response]` .

{% gist https://gist.github.com/mrinalraj/3c16ebf0fb52181250b67d2fff60d242.js %}

Now let’s see what we are doing here. The instance takes in `BaseUrl, options, interceptor` as arguments. The `BaseUrl` is clearly the base API URL needed by the app. The `options` is an object that is passed as the options to the `fetch` function. The last one is a function that implements the checks on the status and returns response accordingly.

Now using this `authRequest` object is very easy and also eliminates `try/catch` to make our code way cleaner. Here is how.

    setLoading(true)

    const [error, response] = await authRequest.get(endpoint)

    if (error) {
        // handle error
    } else {
        // handle success
    }

    setLoading(false)

Let me know how this article helped you in the comments below.

Happy coding.

Thanks to [Pankaj](https://medium.com/@pankajdagar) for suggesting the topic.