Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iteration over FileList, React, Typescript

I'm "Reactifying" a file input and can't manage to iterate over selected files.

private onInputChanged = (e: React.FormEvent<HTMLInputElement>): void => {
  let files: FileList | null =  e.currentTarget.files;
  files.map( file => console.log("Do something with " + file.name));
}
<input 
    type="file"
    onChange={this.onInputChanged}
/>

Here is a barebone example of my problem. FileList cannot be used with .map(... and neither .forEach(...

How can I accomplish an iteration on selected files?

Error: Property 'map' does not exist on type 'FileList'

like image 468
Nikola Sevo Avatar asked Oct 27 '17 14:10

Nikola Sevo


People also ask

How do I iterate over a FileList?

One way to let us loop through each item in a file list object is to convert it to an array with the Array. from method. Then we can use the forEach method on it to loop through the file list entries. The file input has the multiple attribute so that we can select multiple files.

Is FileList an array?

FileList is an object which represents an array of individually selected files from the underlying system.

What is a FileList?

A file list is a file that contains the names and directories of each source file that you want to use in a mapping. Use a file list to enable a task to read multiple source files for one source object in a mapping.


2 Answers

FileList is an Array like object, that has the length property, and indexed values, but it lacks the Array methods, such as map. With ES6 you can use spread or Array#from to convert it to a real array. In ES5 you can call Array#slice to convert to an array, or call the method on the FileList.

Note: If Array#from causes the TypeScript | Array.from | error TS2339: Property 'from' does not exist on type 'ArrayConstructor' error, change the default target (es3) to ES6 - "target": "ES6" - in the compiler options of the "tsconfig.json", or use the --target ES6 in the command line.

Array.from demo:

const onInputChanged = (e) => {
  const files =  e.currentTarget.files;
  
  Array.from(files).forEach(file => console.log("Do something with " + file.name));
}
<input 
    type="file"
    onChange="onInputChanged(event)"
/>

Calling forEach demo:

const onInputChanged = (e) => {
  const files =  e.currentTarget.files;
  
  [].forEach.call(files, file => console.log("Do something with " + file.name));
}
<input 
    type="file"
    onChange="onInputChanged(event)"
/>
like image 72
Ori Drori Avatar answered Oct 17 '22 17:10

Ori Drori


The FileList interface is accessed using the index:

for (let i = 0; i < files.length; i++) {
    console.log(files[i].name);
    //or
    console.log(files.item(i).name);
}

You can use either the index with [0] or via item(0).

like image 1
Fenton Avatar answered Oct 17 '22 18:10

Fenton