Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map through an array of input files?

I have two functions: one that turn files into dataUrl and another that returns a promise with the result:

fileToDataURL(file) {
  var reader = new FileReader()
  return new Promise(function (resolve, reject) {
    reader.onload = function (event) {
      resolve(event.target.result)
    }
    reader.readAsDataURL(file)
  })
}  

getDataURLs (target) {
  // target => <input type="file" id="file">      
  return Promise.all(target.files.map(fileToDataURL))
}

target.files.map returns: TypeError: target.files.map is not a function. H

How to modify getDataUrls so it returns an array with the dataUrls?

like image 748
alex Avatar asked Jun 13 '17 03:06

alex


2 Answers

function getDataURLs(target) {
  // target => <input type="file" id="file">      
  return Promise.all([...target.files].map(fileToDataURL))
}

FileList is not an Array, and does not inherit from Array, but it does implement the iterable protocol, so you can use the spread syntax to get it as an array.

In case you're wondering how to check if a class like FileList supports the spread syntax, you can do this:

console.log(FileList.prototype[Symbol.iterator]);

If that returns a function (which it does), then that returned function is a generator function that is invoked on an instance of the class by the spread syntax.

like image 125
Patrick Roberts Avatar answered Nov 06 '22 20:11

Patrick Roberts


While Patrick Roberts' answer is true, you may face an issue on TypeScript:

issue screenshot

Type 'FileList' is not an array type or a string type. Use compiler option '--downlevelIteration' to allow iterating of iterators. ts(2569)

You can find a complete answer about --downlevelIteration the post Why downlevelIteration is not on by default?.

In our case, to iterate on a FileList, instead of the spread operator, use Array.from():

function getDataURLs(target) {
  // target => <input type="file" id="file">      
  return Promise.all(Array.from(target.files).map(fileToDataURL))
}
like image 3
aloisdg Avatar answered Nov 06 '22 19:11

aloisdg