1

This is a madeup example of the actual situation. For my purpose i need to return a value assigned to a variable which is initialized inside onload event handler. It is returning undefined. Is there any way to return the variable ?

in this case, i need to return the element variable from usefile function.How i can manage that.

<html>

<body>
<input type='file' id='up' accept='image/*' >
<script>
function fileread(e){
    if(window.FileReader && window.File && window.FileList){

       var file=e.target.files[0];
       var getElement=usefile(file);
       console.log(getElement); // prints 'undefined' 

   }    
}
function usefile(file){
   var reader=new FileReader();
   reader.onload=function(e){
       var element=getRandomElement();
       return element; // need to return it and assign it to getElement variable inside fileread function
   }
}
function getRandomElement(){
   var arr=[1,2,3];
   return arr[2]; // a random value for experiment purpose
}
document.getElementById('up').addEventListener('change',fileread,false);

</script>
</body>
</html>
AL-zami
  • 8,902
  • 15
  • 71
  • 130

2 Answers2

1

Returning a value works when you do everything synchronously. The asynchronous part in your case comes from the delay it would take to read a file. So you supply it with a function which is called once the file is read.

This means you also need to structure your code so that the part which has to be executed after the file is read, is called later. Hence you need to move that logic into a callback as well.

In short, Use callbacks. This is one way...

function fileread(e) {
  if (window.FileReader && window.File && window.FileList) {

    var file = e.target.files[0];
    var getElement = usefile(file, function() {
      console.log(getElement); // does not print 'undefined' 
    });
  }
}

function usefile(file, callback) {
  var reader = new FileReader();
  reader.onload = function(e) {
    var element = getRandomElement();
    callback(element);
  }
}

function getRandomElement() {
  var arr = [1, 2, 3];
  return arr[2]; // a random value for experiment purpose
}
document.getElementById('up').addEventListener('change', fileread, false);
<input type='file' id='up' accept='image/*'>
loxxy
  • 12,990
  • 2
  • 25
  • 56
1

Try using FileReader onloadend event

<html>

<body>
  <input type='file' id='up' accept='image/*'>
  <script>
    var reader, result = [];
    if (window.FileReader && window.File && window.FileList) {
      reader = new FileReader();

      function fileread(e) {
        var file = e.target.files[0];
        var getElement = usefile(file);
        reader.onloadend = function(e) {
          console.log(result)
        }
      }

      function usefile(file) {
        reader.onload = function(e) {
          var element = getRandomElement();
          // push `element` , `e.target.result` to `result` array
          result.push(element, e.target.result)
        }
        reader.readAsDataURL(file)
      }

      function getRandomElement() {
        var arr = [1, 2, 3];
        var r = arr[Math.floor(Math.random() * arr.length)];
        return r; // a random value for experiment purpose

      }
      document.getElementById('up').addEventListener('change', fileread, false);
    } else {
      alert("FileReader not supported")
    }
  </script>
</body>

</html>

Alternatively, using Promise

<html>

<body>
  <input type='file' id='up' accept='image/*'>
  <script>
    function fileread(e) {
      if (window.FileReader && window.File && window.FileList) {

        var file = e.target.files[0];
        var getElement = usefile(file);
        getElement.then(function(data) {
            console.log(data[0], data[1])
          })
      }
    }

    function usefile(file) {
      return new Promise(function(resolve) {
        var reader = new FileReader();
        reader.onload = function(e) {
          var element = getRandomElement();
          // resolve `Promise` with `element` , result of `FileReader`
          resolve([element, e.target.result])
            // return element; 
            // need to return it and assign it to getElement variable
            //  inside fileread function
        }
        reader.readAsDataURL(file)
      })
    }

    function getRandomElement() {
      var arr = [1, 2, 3];
      var r = arr[Math.floor(Math.random() * arr.length)];
      return r; // a random value for experiment purpose
    }
    document.getElementById('up').addEventListener('change', fileread, false);
  </script>
</body>

</html>
guest271314
  • 1
  • 15
  • 104
  • 177