Search code examples
progress-barvuejs2progressaxios

Progress bar with Vue and Axios


I'm making an image uploader, and I'd like to display a progress bar which starts incrementing once a file is selected.

I'm using Axios to access the backend, and have it setup like this:

const BASE_URL = 'http://localhost:3000';

function uploadImage(data, listingId) {
  const url = `${BASE_URL}/listings/${listingId}/images`;
  let config = {
    onUploadProgress(progressEvent) {
      var percentCompleted = Math.round((progressEvent.loaded * 100) /
        progressEvent.total);
      return percentCompleted;
    },
  };
  return axios.post(url, data, config).
      then(x => x.request.response).
      catch(error => error);
}

How can I access the percentCompleted from the Vue side below?

inputDidChange(e) {
  let inputData = e.target.files[0];
  var formData = new FormData();
  formData.append('image', inputData);
  uploadImage(formData, this.listingId).
    then((x) => {
      var xParsed = JSON.parse(x);
      this.newFile = xParsed.image.image.url;
      this.files.push(this.newFile);
      console.log('success');
  });
},

Solution

  • Pass a callback to your uploadImage function.

    function uploadImage(data, listingId, onProgress){
      const url = `${BASE_URL}/listings/${listingId}/images`;
      let config = {
         onUploadProgress(progressEvent) {
          var percentCompleted = Math.round((progressEvent.loaded * 100) /
            progressEvent.total);
    
          // execute the callback
          if (onProgress) onProgress(percentCompleted)
    
          return percentCompleted;
        },
      };
      return axios.post(url, data, config).
          then(x => x.request.response).
          catch(error => error);
    }
    

    And then pass in a Vue method.

    methods:{
      onProgress(percent){
        //update vue
      },
      inputDidChange(e) {
        let inputData = e.target.files[0];
        var formData = new FormData();
        formData.append('image', inputData);
        uploadImage(formData, this.listingId, this.onProgress).
          then((x) => {
            var xParsed = JSON.parse(x);
            this.newFile = xParsed.image.image.url;
            this.files.push(this.newFile);
            console.log('success');
        });
      },
    }