AG_HIHI
AG_HIHI

Reputation: 1995

Axios: onUploadProgress event gets only triggered after video is uploaded completely

I am trying to track the progress of video upload and accordingly display it to the user.
This is the axios request that uploads the video.

  const config = {
    onUploadProgress: function (progressEvent) {
      var percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      console.group("profileActions.uploadProfileVideoURL");
      console.log("progressEvent.loaded: ", progressEvent.loaded);
      console.log("progressEvent.total: ", progressEvent.total);
      console.log("percentCompleted: ", percentCompleted);
      console.groupEnd();
    },
  };

  axios
    .post("/api/profile/uploadProfileVideoURL", videoData, config)

The problem is that it only gets triggered when video is completely uploaded.
I have found this discussed in this Github Axios Issue:

Only 100% can be fired in case your upload files are too small, or download/upload speed is too fast. Try to upload 10mb file maybe.

So I tried uploading a 100Mb video, and the event still gets triggered at then end of the upload.
Any idea why is this happening?
And can I fine-tune axios for the event to get triggered at certain progress values?

Upvotes: 4

Views: 4757

Answers (1)

Mohammad Oftadeh
Mohammad Oftadeh

Reputation: 1449

Your code needs added the FormData and some headers, like (MIME type of the file) for request. You can use this logic:

First - create a utility function for handling upload with progress like below:

import axios from "axios";

const Upload = (files, customHeader, cbProgress, cb) => {
  const config = {
    onUploadProgress: function (progressEvent) {
      var percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      cbProgress(percentCompleted);
      console.log(percentCompleted);
    },
    headers: {
      ...customHeader,
      // "Content-Type": files[0].type,
      // "Content-Type": "multipart/form-data",
    },
  };

  let data = new FormData();
  data.append(<field_name>, files[0]); // Name of the field for uploading

  console.log({ ...customHeader });

  axios
    .post(<url>, data, config)
    .then((res) => cb(res))
    .catch((err) => console.log(err));
};

export default Upload;

Short description of the above code:

  • customHeader: pass any headers to the config, For example: "Content-Type", "Authorization", etc...

  • cbProgress: This is a callback, When the function is invoked and in progress.

  • cb: This is a callback, When the function is invoked and upload is completed.

Note: FormData, Used to send the file and you must use it.

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to "multipart/form-data".

Finally - You can call this utility function anywhere you want like below:

const customHeader = {
    "Content-Type": files[0] && files[0].type, // This is an example
    "Content-Type": "multipart/form-data", // This is an example
  };

  Upload(
    files,
    customHeader,
    (percent) => {
      // ...
    },
    (res) => {
      // ...
    }
  );

Upvotes: 3

Related Questions