0

this is my Html5 code :

<div>
    <input type="file" multiple (change)="comPress($event.target.files)">
</div>

i need on change do this function comPress() with all files. this is in Angular component.ts :

comPress(images){
   function fetchResult(img) {
    return new Promise(  function(resolve, reject) {

      let data = [];
      for(let i of img){
      var reader = new FileReader();
        reader.onload = function (e) {
          data = [...data, e.target['result']];
        }
        reader.readAsDataURL(i);
      }

       resolve(data);
       reject('reject');
    })

  };

  fetchResult(images).then(data=>{
    console.log(data) // is always []
  }).catch(err=>console.log(err))

}

i need push this variable let data = []; with all result data from function onload()

but the result is always [] empty array!

I expect this result :

["data:sadvdsbdsbdsvdsvdsbdb", "data:vaswbvewbewbregergreg"]

What is wrong with this code?

  • 4
    You resolve the promise *outside* the asynchronous operation? – jonrsharpe Jul 24 '19 at 18:41
  • how do this with input file ? is not working outside the ```comPress()``` – emad alhamou Jul 24 '19 at 18:44
  • I would suggest creating an array of promises and using `Promise.all` to combine them. Or using `async/await`. Or do something like the answers to [Callback after all asynchronous forEach callbacks are completed](https://stackoverflow.com/q/18983138/215552)... – Heretic Monkey Jul 24 '19 at 18:52
  • Why are you rejecting the promise immediately after resolving it? –  Jul 24 '19 at 19:03
  • The whole point of the promise executor with its callback arguments is that you can call `resolve` after the asynchronous stuff happened - in the `onload` listener. – Bergi Jul 24 '19 at 20:04

2 Answers2

1

After the loop ends, your onload handlers are still not run. So data is not populated. What you can do first is this:

function readFile(i) {
  return new Promise(success => {  
    const reader = new FileReader();
    reader.onload = e => {
      success(e.target['result']);
    };
    reader.readAsDataURL(i);
  });
}

You get a promise that resolves with the actual data from FileReader. Then in your main code:

return Promise.all(img.map(i => readFile(i)));
TPReal
  • 1,539
  • 12
  • 26
0

the problem with your code is that promise is resolved before on load event is called thus resulting in empty array what you need to do is resolve your promise in onloadend event i.e

reader.onloadend = function() {
  resolve(data)
}
Aimal Khan
  • 449
  • 2
  • 9