Implementing a file upload status progressbar with Axios onUploadProgress using React hooks

Bino Bose
3 min readDec 11, 2020

--

There are situations when we have to display the upload status for better user experience, be it a small file or a huge file or even multiple files. However, tracking the status and display it on a normal scenario would be difficult, especially when the file size is huge. At this point, the Axios event `onUploadProgress` comes in handy. We can attach a method to this event with progressEvent as the parameter, which could in turn be used to determine at what position we are in the uploading process. Let me explain this quickly through a simple code snippet.

Here I am using React hooks to implement this functionality.

In this example consider I am using an html file input, which will accept the files, and then call the axios.post that has an implementation of `onUploadProgress` event to track the progress of the file uploaded by passing it to a react-bootstrap progressbar.

First I will import the necessary libraries.

import React, { useState } from ‘react’
import axios from ‘axios’
import ProgressBar from ‘react-bootstrap/ProgressBar’

Inside the module we need to call useState hook to get and set the value of the current percentage that we need to pass to the progressbar.

const [percentage, setPercentage] = useState(0) // we will set it as zero initially

Then in the upload method, we need to initialize the percentage and the formdata for the file upload

let percent = 0
let data = new FormData()

data.append(‘files’, e) //Here e is the file that’s currently being uploaded

Next I will add a config param that needs to be passed to the Axios post, and will trigger the onUploadProgress event.

const config = {
onUploadProgress: (progressEvent) => {
const {loaded, total} = progressEvent;
percent = Math.floor((loaded * 100) / total)
console.log( `${loaded}kb of ${total}kb | ${percent}%` ) // just to see whats happening in the console

if(percent <= 100) {
setPercentage(percent) // hook to set the value of current level that needs to be passed to the progressbar
}
},
headers: {
// custom headers goes here
}
}

In the above code snippet, we are calling the onUploadProgress event with progressEvent as a parameter, which will in turn capture the loaded and total values. These are the values that we need to calculate the current status.

Once these values are set, we will have to calculate the current upload percentage like this,

percent = Math.floor((loaded * 100) / total)

Now we need to pass this current value to the progressbar. For this I am using useState hook setPercentage to set the current value, and only if its less than or equal to 100, as we need to show the progressbar only until 100.

In my case I had a few custom headers to be passed to the axios post, but however that is optional in most of the case.

Next we need to pass the params into the Axios

const postResponse = axios.post(‘/some url’, data, config)
.then(res => {
setPercentage(percent), () => {
setTimeout(() => {
setPercentage(0)
}, 1000);
}
})
.catch((error) => {
console.error(‘Upload Error:’, error)
})
postResponse.then(() => {
console.log(‘File uploaded successfully.’)
}
)

In the above code we are setting a timeout so that the we will get enough leverage to assign the percentage value to the useState hook and finally reset it to zero.

In addition to this, I am passing the axios.post to a postResponse constant so that, once the file upload is success, I can hide the progressbar programmatically.

And finally for the progressbar, we will pass the percentage value like this, but only if the percentage is greater than zero

{percentage > 0 && <ProgressBar now={percentage} active />}

Above is just a simple code snippet, to showcase the onUploadProgress event in Axios.

--

--