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." ... π€
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. 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
Github/MatthewPalmer9
Twitter/@MattPDev
Top comments (1)
I like to put my "unloader" in finally() hook of promise. Makes more sense to me
Great article!