Home > Mobile >  How do I wait for FileReader onload to complete first
How do I wait for FileReader onload to complete first

Time:01-03

I am working with FileReader and I have come across an issue with the onl oad method of FileReader not being executed synchronously with the rest of the code. Basically I have 2 functions like these:

    imageExists(url, callback) {
      var img = new Image();
      img.onload = function () { callback(true); };
      img.onerror = function () { callback(false); };
      img.src = url;
    }

    isImageCorrupt(file): boolean {
      var reader = new FileReader();
      var isCorrupt = false;
      reader.readAsDataURL(file);
      reader.onload = (e) => {
        this.imageExists(e.target.result, (exists) => {
            if (exists) {
                isCorrupt = false;
                // Image is not corrupt
            } else {
                isCorrupt = true;
                //Image is corrupt
            }
        });
    };

    return isCorrupt;
   }

The isImageCorrupt() function calls the reader.onLoad which calls the imageExists callback function, which also contains a image onl oad method.

The problem is that during the execution of the isImageCorrupt() function, the reader.onLoad has not changed the value of isCorrupt yet but the function has returned the value in the last line which is always false.

I want my function to wait for the reader.onLoad to finish its execution before the function returns the value.

CodePudding user response:

maybe something like this?

 isImageCorrupt(file): Promise<Boolean> {
    return new Promise((resolve) => {
        var reader = new FileReader();
        reader.onload = (e) => {
            var img = new Image();
            img.onload = function () {
              resolve(false);
            };
            img.onerror = function () {
              resolve(true);
            };
            img.src = <string>e.target.result;
        }
        reader.readAsDataURL(file);
    });
}

*disclaimer: I did not test it

CodePudding user response:

You could use Promises. The code could be still refactorized using async/await

    isImageCorrupt(file): Promise<boolean> {
      return new Promise<boolean>((resolve,reject)=>{
      var reader = new FileReader();
      
      reader.readAsDataURL(file);
      reader.onload = ()=>{
      var img = new Image();
      img.src = reader.result;
            img.onload = function () {
              resolve(false);
            };
            img.onerror = function () {
              resolve(true);
            };
            
}

reader.onerror=()=>{reject(true)}
        });
    };


   
       isImageCorrupt(yourFile).then((result)=>{/*HERE USE RESULT*/},(error)=>{HERE USE ERROR RESULT})

However you shouldn't return true o false, but resolve if it's ok and reject otherwise, whithout a boolean value in this way

isImageCorrupt(file): Promise<void> {
          return new Promise<void>((resolve,reject)=>{
          var reader = new FileReader();
          
          reader.readAsDataURL(file);
          reader.onload = ()=>{
          var img = new Image();
          img.src = reader.result;
                img.onload = function () {
                  resolve();
                };
                img.onerror = function () {
                  reject();
                };
                
    }
    
    reader.onerror=()=>{reject()}
            });
        };
    
    
       
       

     isImageCorrupt(yourFile).then(()=>{/*HERE OK*/},()=> {HERE 
  THERE WAS SOME ERROR/PROBLEM})
  • Related