Filtering files in svelte

Viewed 121

recently i followed some posts on stack overlflow about import some files in svelte, and this is the code:

<script>

    let files = [];
    
    function contentArray(ev){
        files = [...files, ...ev.target.files.filter(f => !files.includes(f))]
    }
    </script>
    
    
    <input type='file' multiple on:change={contentArray} accept=".txt">
    {#each files as file}
        <p>The imported file is: {file.name}</p>
    {#await file.text() then text}
        <pre>{text}</pre>
    {/await}
    {/each}

My goal is when I import a file, if I try to import it again, the program simply don't show it. I tried with the filter method but it gives me this error:

ev.target.files.filter is not a function or its return variable is not iterable

I searched a bit online, but i cannot understand where i made a mistake. Thanks in advance.

1 Answers

ev.target.files is not an array but a FileList (FileList docs on MDN) and, as such, doesn't have the filter() method.

So, to use filter(), you have to convert the FileList to an array first which you can do like this:

let arrayFileList = [...ev.target.files];

// now you can arrayFileList.filter(...)

Also, comparing the File objects when you do !files.includes(f) might not give you the desired result depending on your setup. So you might still end up with the same file multiple times. This is because when adding the same file multiple times to your <input type="file">, the corresponding File instances might not be the same. So you might want to compare based on the name as in

arrayFileList.filter(f => !files.some(ff => ff.name === f.name));
Related