Axios all progress bar for multiple async uploads

Viewed 3064

I'm trying to get the upload progress to show both the current file's upload progress, but also the total progress when uploading multiple files at once. I can't use the classic way with .loaded/.total, since onUploadProgress gets called multiple times by the different async requests, so the percentage will just jump back and forth. With my code below I can at least show the progress for remaining files (e.g. 33% when 1 of 3 files has been uploaded), but it doesn't take into consideration how much of the file has loaded (so it stays at 0% until the whole file is up, then it jumps to 33% in a second).

requests.push(
  axios.post(this.uploadUrl, formData, {
    onUploadProgress: progressEvent => {
      if (progressEvent.loaded === progressEvent.total) {
        this.progress.current++
      }

      // this.progress.percent = parseInt(Math.round((progressEvent.loaded * 100) / progressEvent.total))
      this.progress.percent = parseInt(Math.round((this.progress.current * 100) / this.progress.total))
    }
  })
)

axios.all(requests)

My problem is that I don't know the progressEvent.total of all files and I can't distinguish the single requests. Also there is no onUploadStart where I could fetch the total and sum it. Can anyone help me out with this? Leave a comment if you have questions or something's unclear (I hope it's somewhat comprehendible)

1 Answers

If by any chance someone stumbles upon this problem, I finally fixed it with the following code. The trick was to calculate each files progress, save it into an object (using the filename as key), then summing the progresses and dividing by the total file count.

// loop through all files and collect requests
for (let file of files) {
  let formData = new FormData()
  formData.append(file['name'], file)

  requests.push(
    axios.post(this.uploadUrl, formData, {
      onUploadProgress: progressEvent => {
        if (progressEvent.loaded === progressEvent.total) {
          this.progress.current++
        }
        // save the individual file's progress percentage in object
        this.fileProgress[file.name] = progressEvent.loaded * 100 / progressEvent.total
        // sum up all file progress percentages to calculate the overall progress
        let totalPercent = this.fileProgress ? Object.values(this.fileProgress).reduce((sum, num) => sum + num, 0) : 0
        // divide the total percentage by the number of files
        this.progress.percent = parseInt(Math.round(totalPercent / this.progress.total))
      }
    })
  )
}
Related