2

I am trying to display the progress for the files uploads in my React app.

First, I have created this function to upload multiple files:

  const [files, setFiles] = useState([])
  const saveDocuments = () => {
    try {
      files.forEach((file) => {
        axios.post("/api/documents", formData, {
          let formData = new FormData();
          formData.append("attached_file", file);
          formData.append("name", file.name);
          headers: {
            "X-CSRFTOKEN": getCookie("csrftoken"),
            "Content-Type": "multipart/form-data",
          },
          onUploadProgress: (progressEvent) => {
            const percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            file.progress = percentCompleted;
            console.log(percentCompleted);
          },
        });
      });
    } catch (e) {
      console.log(e);
    }
  };

With this code, I can see in the console the percentCompleted value.

And in my render function, I'm trying to display this progress value:

return(
  <ul>
    {files.map((file, index) => (
      <li key={index} >
        <div>{file.name}</div>
        <div>{file.progress} %</div>
      </li>
    ))}
  </ul>;  
)

The progress value does not display ; but the react dev tools shows the progress value in the state.

I guess I am not updating correctly the state of my file object. How can I deal with this? Thanks for helping.

4
  • You are not setting any state in saveDocuments. Commented May 5, 2021 at 8:22
  • files is an array of my state (I've uploaded the code to indicate that). Commented May 5, 2021 at 13:28
  • Doesn't look like you are updating your files state anywhere. You would need to call the setFiles function somewhere for the state to actually update. Commented Jun 18, 2021 at 20:46
  • I have fixed this already til my question, i will post my solution soon Commented Jun 20, 2021 at 8:49

1 Answer 1

4

So I found out the solution, I have to create a copy of my array files with a new key progress which has the value of percentCompleted

const saveDocuments = () => {
    try {
      files.forEach((file) => {

        axios.post("/api/documents", formData, {
          let formData = new FormData();
          formData.append("attached_file", file);
          formData.append("name", file.name);
          headers: {
            "X-CSRFTOKEN": getCookie("csrftoken"),
            "Content-Type": "multipart/form-data",
          },
          onUploadProgress: (progressEvent) => {
            const percentCompleted = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );
            // Create copy of file
            let newFile = file;
            // ... and set the progress
            newFile.progress = percentCompleted;
            // Create copy of files array
            let filesCopy = [...files];
            // Find the index of the file object
            let fileIndex = filesCopy.findIndex((el) => el.name === file.name);
            //... and replace the object with the new one containing the [progress] key
            filesCopy[fileIndex] = newFile;
            // Finally, update the state
            setFilesUploaded([...filesCopy]);
            file.progress = percentCompleted;
          },
        });
      });
    } catch (e) {
      console.log(e);
    }
  };

Then, the render function returns the new array containing objects with the progress key:

return(
  <ul>
    {filesUploaded.map((file, index) => (
      <li key={index} >
        <div>{file.name}</div>
        <div>{file.progress} %</div>
      </li>
    ))}
  </ul>;  
)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.