Create an upload progress bar with Axios

Reading Time: 2 minutes 🕑

Last updated: September 14, 2022.

Using the Axios HTTP client in JavaScript, you can track the progress of an upload made using the POST or PUT method and use this information to update a progress bar.

Table of contents

Setup

Import Axios

First, you need to import Axios into your project. In this tutorial, we’ll use the CDN link provided by the cdnjs server.

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/1.0.0-alpha.1/axios.min.js"></script>

Create HTML form with file upload

To have something to upload, create a form with an <input> element of type file as well as a button to submit the form:

<!-- Form -->
<form id="form">
    <input type="file" accept=".png, .jpg" id="file">
    <button type="submit">Upload file!</button>
</form>

Next, create the progress bar. This is simply a <progress> element. Text to accompany the bar can be displayed in a label:

<!-- Progress bar -->
<div>
    <label for="progress-bar">0%</label>
    <progress id="progress-bar" value="0" max="100"></progress>
</div>

Handling form submission

Now, in JavaScript, you can handle the form submission by appending the image to a new FormData object:

const form = document.getElementById('form');
const bar = document.getElementById('progress-bar');

form.addEventListener('submit', function(e) {
  e.preventDefault();
  const formData = new FormData();
  const file = document.getElementById('file');
  const img = file.files[0];
  formData.append('image', img);

  // POST request to be added here
})

Now, you can send this payload as part of a POST request using Axios.

Tracking upload progress

To track the status of the upload, pass in a configuration object after the payload with the property onUploadProgress. The value should be a function. This is fired continually during the request.

As a parameter, you have available an object providing information on upload progress. Divide total (total size of upload) by loaded (uploaded so far) to calculate a percentage complete. Then use this to update the progress bar and its label value:

const form = document.getElementById('form');
const bar = document.getElementById('progress-bar');

form.addEventListener('submit', function(e) {
  e.preventDefault();
  const formData = new FormData();
  const file = document.getElementById('file');
  const img = file.files[0];
  formData.append('image', img);

// Axios
const config = {
  onUploadProgress: function(progressEvent) {
    const percentCompleted = Math.round((progressEvent.loaded / progressEvent.total)*100);
    bar.setAttribute('value', percentCompleted);
    bar.previousElementSibling.textContent = `${percentCompleted}%`
    if (percentCompleted === 100) {
      bar.previousElementSibling.textContent = `Upload complete!`
    }
  }
}

axios.post('https://httpbin.org/post', formData, config)
  .then(res => console.log(res))
  .catch(err => console.log(err))
})

In this example, the POST request is made to a test endpoint provided by httpbin.org.

Testing tips

For testing, it is a good idea to simulate a slower internet connection so that you have a better chance to see the progress bar in action.

To do so, navigate to the network tab in the developer tools of your browser and add ‘throttling’. For example, Chrome offers a ‘Slow 3G’ preset that you can apply.

Related links