LOADING. . . For User Experience
Tags: react, javascript, html, css
Published: 2020-11-16 19:49:28

# Introduction
If you're familiar with `fetch()` requests in JavaScript and React, then you've likely used Heroku to deploy your back-end APIs. If you're using the free version, you know that Heroku puts servers to sleep... OFTEN. This can be frustrating for users waiting upwards of 10 seconds for information to display on a webpage -- OUCH! So, how can we solve this problem? If only... there was a way to convey to them "Hey, hold on just one moment while we retrieve some information." ... :thinking:

### Problem SOLVED!
Now, some of you may have a different approach. Personally, I find this method to be short and sweet. It keeps your code clean and is easily readable.

Let's assume that you have a React application with a products page. Before loading those products, you're using `componentDidMount()` to call upon a function dedicated to fetching them called `fetchProducts()`.

This might be what that function looks like:

```
export function fetchProducts(){
    return (dispatch) => {
        fetch('https://your-api-url.com/products')
        .then(resp => resp.json())
        .then(products => dispatch({ 
            type: 'RENDER_PRODUCTS', 
            payload: products
        }))
    }
}   
```

**NOTE: Don't worry if you're confused by what you're looking at. I copied a real example from one of my own projects utilizing Redux. Just know, for this example, the syntax you see isn't too important.**

Now, right above `return (dispatch) => {`, we can apply a `loader()` function, which can be defined within our `fetchProducts()` function. See the example below:

```
export function fetchProducts(){
    const loader = () => { // new function
        const loaderDiv = document.querySelector("div#loader");
        loaderSpan.innerHTML = "FETCHING PRODUCTS . . .";
    }

    return (dispatch) => {
        loader() // new code
        fetch('https://your-api-url.com/products')
        .then(resp => resp.json())
        .then(products => dispatch({ 
            type: 'RENDER_PRODUCTS', 
            payload: products
        }))
    }
}   
```

Perfect! So now we have the `loader()` function executing PRIOR to our `fetch()` request. This is setting the `innerHTML` of our `querySelector` selection to "FETCHING PRODUCTS. . .". The next issue is making that disappear when we receive a response from our server. This is easily accomplished by creating a new function called `unloader()` and executing it within our `fetch()` request. Check it out:

```
export function fetchProducts(){
    const loader = () => {
        const loaderSpan = document.querySelector("div#loader");
        loaderSpan.innerHTML = "FETCHING PRODUCTS . . .";
    }

    const unloader = () => { // new function
        setTimeout(() => {
            const loaderSpan = document.querySelector("div#loader");
            loaderSpan.innerHTML = ""
        }, 1000);
    }

    return (dispatch) => {
        loader()
        fetch('https://your-api-url.com/products')
        .then(resp => resp.json())
        .then(unloader()) // New code
        .then(products => dispatch({ 
            type: 'RENDER_PRODUCTS', 
            payload: products
        }))
    }
}   
```

**NOTE: You don't have to set a timeout, but it takes about a second or less for the information to load. Maybe a full second might be overkill. Regardless, I'll leave that approach up to you!**

And there we have it! Easy-peasy, right?
If you're interested in seeing this in action, [follow this link](https://bowliciousbowtique.vercel.app/products). This is where I implemented this feature in my own project.


# Conclusion
There are extended uses when it comes to `fetch()` requests. They not only handle response data, but they can execute functions as well through their `.then()` methods. Isn't asynchronous programming fun? I hope this helps some of you out there on a budget! 

### Connect with me!
[LinkedIn/MatthewPalmer9](https://www.linkedin.com/in/matthewpalmer9)
[Github/MatthewPalmer9](https://www.github.com/matthewpalmer9)
[Twitter/@MattPDev](https://www.twitter.com/MattPDev)