Home > database >  Can't pass video file from  page.svelte to  page.server.ts in a form
Can't pass video file from  page.svelte to  page.server.ts in a form

Time:10-02

I'm trying to move my submit video upload functionality from the client to the server. However, I'm struggling with passing the video file to the server in a form.

I'm using "svelte-file-dropzone" to retrieve the file, some processing is done and then I'm trying to submit the file through a hidden file input tag like this:

<form  action="?/upload" method="POST" enctype="multipart/form-data" use:enhance={handleSubmit} id="upload" name="upload">
    <input hidden type="file" id="accepted-file" name="accepted-file" accept="video/*" bind:value={accepted}>

    <div >
        <div >
            <button type="submit" >Submit Video</button>
        </div>
    </div>
</form>

When I console log the value "accepted" on the client side, everything is as it should be:

{
    path: "test.mov"
    lastModified: 1640425487561
    lastModifiedDate: Sat Dec 25 2021 01:44:47 GMT-0800 (Pacific Standard 
        Time) 
    name: "test.mov"
    size: 12458107
    type: "video/quicktime"
    webkitRelativePath: ""
}

...but when I try to access the file on the server:

export const actions: Actions = {
    async upload({ request }) {
        const uploadFormData = await request.formData();

        const accepted = uploadFormData.get('accepted-file') as File;
        console.log("accepted file: ", accepted);

        return { accepted };
    }
}

...there's no file, i.e., "accepted" is blank.

I'm thinking that the problem may have something to do with how I'm attaching the file to the hidden input but am not too sure.

It's worth noting that my code works in all other circumstances, it only seems to fail in this instance. I've tried many workarounds but can't seem to be able to access the file no matter what I try.

I've been struggling with these new SvelteKit changes and also this is my first attempt at using TypeScript. Any thoughts or suggestions would be greatly appreciated, as I'm currently completely lost. Thank you for your time.

CodePudding user response:

You cannot simply set a file input value like this. To actually send your file, you have to modify the files list of the file input.

E.g.

<input type="file" name="accepted-file"
    style:display="none"
    use:setFile />
/** Svelte action to transfer the file to the input */
function setFile(input: HTMLInputElement) {
    const data = new DataTransfer();
    data.items.add(accepted); // Assuming that `accepted` is a File instance
    input.files = data.files;
}

(If the input always exists and is not only created once after the file has been processed, you can use bind:this instead of an action to get a reference to the input and then update the files wherever you do the processing. You could also wrap the input in #key accepted to force its recreation.)

  • Related