4

The reader.onloadend calls a async function addData and reader.onloadend is in a loop.

const uploadFiles = () => {
    console.log(acceptedFiles)
    setLoading(true)
    console.log(loading)
    let i = 0
    let l = acceptedFiles.length

    for (i = 0; i < l; i++) {
      let file = acceptedFiles[i]
      const reader = new window.FileReader()
      reader.readAsArrayBuffer(file)
      reader.onloadend = () => {
        let buffer = Buffer(reader.result)
        console.log(buffer)
        addData(file.path, buffer)
      }
    }
  }

This is my async function addData

async function addData(name, buffer) {
    const file = await myfunction()
    
  }

I want to call setLoading(false) after all the async addData in the loop has been called. The onClick function doesn't work, loading is set to false when I click the button before all the async function is done.

const [loading, setLoading] = useState(false)
<button onClick={() => {
                uploadFiles()
                 setLoading(false) 
             }}
            disabled={loading}
          >
3
  • 1
    Promises...... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Feb 2, 2021 at 17:45
  • Why not writing setLoading(false) after for loop inside uploadFiles Commented Feb 2, 2021 at 17:55
  • @ZainUlAbideen And that will set it to false before all the files have been read. Commented Feb 2, 2021 at 17:58

1 Answer 1

5

Using promises you can know when all of the files have been read. Basic idea below

const uploadFiles = (evt) => {

  // set loading to true;

  const acceptedFiles = [...evt.target.files];

  // Create a map of promises that will resolve when file is read
  const readerPromises = acceptedFiles.map(file => {
    return new Promise(resolve => {
      const reader = new window.FileReader()
      reader.readAsArrayBuffer(file)
      reader.onloadend = () => {
        console.log(file);
        let buffer = reader; // Buffer(reader.result)
        resolve([file.name, buffer])
      }      
    });
  });

  // Detects when all of the promises are fully loaded
  Promise.all(readerPromises).then(results => {
    console.log(results);
    // set loading to false;
  });
  
};
<input type="file" multiple onchange="uploadFiles(event)" />

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.