0

I need to load multiple image asynchronously from file field and them check if the dimensions are valid or not. I am pretty close, I just need to get the height of previously loaded image on call back. This is my effort so far:

let  files = this.fileUpload.files; //get all uploaded files 
   for (var i = 0, f; f = files[i]; i++) { //iterate over uploaded file
      console.log(f);
      let img = new Image();
      img.name=f.name;
      img.size=f.size;



       img.onload = () =>{alert(img.height)} //it is giving height here

      if (img.complete) { //callback 
           alert(img.name + 'loaded');
           load_count++;
           library_store.uploaded_image.push(
                                              {
            height:img.height,
            width:img.width, // not coming, just wondering how to get 
                             //the image height from load
            name:img.name,
            size:img.size
                                              }
                                           );
 }
if(load_count === uploaded_file_count){ // if all files are loaded
 //do all validation here , I need height and width here 
}

What is the best way to do this?

2 Answers 2

2

Wouldn't you want to move library_store logic to img.onload? Like below:

let  files = this.fileUpload.files; //get all uploaded files 
for (var i = 0, f; f = files[i]; i++) { //iterate over uploaded file
    console.log(f);
    let img = new Image();
    img.name=f.name;
    img.size=f.size;

    img.onload = function() {
        // hoping that ```this``` here refers to ```img```
        alert(this.name + 'loaded');
        load_count++;
        library_store.uploaded_image.push({
            height:this.height,
            width:this.width,
            name:this.name,
            size:this.size
        });

        if(load_count === uploaded_file_count){ // if all files are loaded
            //do all validation here , I need height and width here 
        }
    }

    // img.onload = () =>{alert(img.height)} //it is giving height here
    /*
    if (img.complete) { //callback 
        alert(img.name + 'loaded');
        load_count++;
        library_store.uploaded_image.push({
            height:img.height,
            width:img.width,
            name:img.name,
            size:img.size
        });

        if(load_count === uploaded_file_count){ // if all files are loaded
        //do all validation here , I need height and width here 
        }
    }
    */
}
Sign up to request clarification or add additional context in comments.

1 Comment

Onload is asynchronous , so it wont help . I tried this already
1

First let's see why you will always fall in this if(img.complete) block even though your images have not been loaded yet:

The complete property of the HTMLImageElement only tells if its resource is being loaded at the time you get the property.

It will report true if the loading succeed, failed, and if the src has not been set.

var img = new Image();
console.log('no-src', img.complete);
img.onerror = function() {
  console.log('in-error', img.complete);
  img.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg=="
};
img.onload = function() {
  console.log('in-load', img.complete);
}
img.src = "/some/fake-path.png";
console.log('while loading', img.complete);

And, at the time you get it, you didn't set this src attribute yet, so it will report true even though your image has not yet loaded its resource.


So what you want is an image preloader:

function preloadImages(srcArray, mustAllSucceed) {
  return Promise.all(srcArray.map(loadImage));

  function loadImage(src) {
    return new Promise((resolve, reject) => {
      var img = new Image();
      img.onload = success;
      img.onerror = mustAllSucceed ? success : reject;
      img.src = src;

      function success() {
        resolve(img)
      };
    });
  }
}
preloadImages(['https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg', 'https://upload.wikimedia.org/wikipedia/commons/9/9b/Gran_Mezquita_de_Isfah%C3%A1n%2C_Isfah%C3%A1n%2C_Ir%C3%A1n%2C_2016-09-20%2C_DD_34-36_HDR.jpg'])
  .then(images => {
    images.forEach(img => console.log(img.src, img.width, img.height));
  }, true);

2 Comments

I need to check the height and width of mutiple uploaded image . I load it asynchronously and need to check if all image has been loaded or not and then get height and width of each image on seperate array for validation rules
You solution looks good but I am unable to make it in react jsx

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.