2

I have previously been testing a component using the following code

<script>
import x from "/path/to/x.json"
</script>

this, as expected loads the json file to variable x.

What I would like to do, is dynamically load a local json file given an <input> element e.g.

<script>
let files ;
function loadJSONFile(){
  doSomething(files[0].name) ;
}
</script>

<input type="file" bind:files on:change={loadJSONFile}>

where doSomething() is doing the equivalent task of import in the first example.

Ideally, I could load the data from any local folder, so bind:files may not be appropriate, as files[0].name seems to yield a relative path, rather than an absolute path.

2
  • 1
    What do you mean by "local folder"? Local to the application or the user? Commented Oct 4, 2022 at 7:40
  • Local to the user @H.B. Commented Oct 4, 2022 at 7:59

1 Answer 1

3

To read a user-provided file, you can use the FileReader API or the newer text() function from the Blob prototype. The best place to do that would be the change event.

(If the user cancels the dialog, the files will be cleared.)

<!-- using .text() -->
<script>
    let json;
    
    async function onChange(e) {
        const file = e.target.files[0];
        if (file == null) {
            json = null;
            return;
        }
        
        json = JSON.parse(await file.text());
    }
</script>

<input type=file on:change={onChange} accept=".json"/>
<pre>{JSON.stringify(json, null, '  ')}</pre>

REPL

<!-- using FileReader -->
<script>
    let json;
    
    async function onChange(e) {
        const file = e.target.files[0];
        if (file == null) {
            json = null;
            return;
        }
        
        json = await readJsonFile(file);
    }

    function readJsonFile(file) {
        const reader = new FileReader();
        return new Promise((resolve, reject) => {
            reader.onload = () => resolve(JSON.parse(reader.result));
            reader.onerror = reject;
            reader.readAsText(file);
        });
    }
</script>

<input type=file on:change={onChange} accept=".json"/>
<pre>{JSON.stringify(json, null, '  ')}</pre>

REPL

Sign up to request clarification or add additional context in comments.

1 Comment

This answered my question exactly, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.