Emokores's avatar

Cannot upload file in update() method

I have a form that receives data, including an input to upload a zip file. However, when I try to upload a file, I get validation errors on all required fields, yet they already contain data, since it is an edit form. The store() method works fine.


public function update(StoreTasksRequest $request, Task $task): RedirectResponse
    {
        if ($request->hasFile('file_url')) {
            if (Storage::exists($task->file_url)) {
                Storage::disk('local')->delete($task->file_url);
            }
            $path = $request->file('file_url')->store('zips');
        }

        $task->update([
            'task_name' => $request->task_name,
            'due_date' => $request->due_date,
            'start_date' => $request->start_date,
            'file_url' => $path ?? "",
            'priority' => $request->priority,
            'status' => $request->status,
        ]);

        return redirect(route('resources.tasks.index'))->with('message', 'Task has been updated successfully.');

    }

So the image cannot upload. I don't know what I'm doing wrong!

0 likes
22 replies
Sinnbeck's avatar

Did you forget enctype="multipart/form-data" on the form?

Emokores's avatar

@Sinnbeck I actually indicated it in the form. I'm using inertia with React:


<Form encType="miltipart/form-data">
       //all fields here ...
</Form>

Emokores's avatar

@Sinnbeck This is the code:


const handleFiles = (e) => {
        setData({ ...data, [e.target.name]: e.target.files[0] });
};

const submit = (e) => {
        e.preventDefault();
        data.file_url = inputRef.current.files[0];

        // console.log(inputRef.current.files[0]);

        post(route("resources.tasks.update", task.id), {
            __method: "put",
            file_url: data.file_url,
        });
    };

const {
            data,
            setData,
            processing,
            errors,
            post,
            progress,
            delete: destroy,
        } = useForm({
            id: task.id,
            task_name: task.task_name,
            due_date: task.due_date,
            start_date: task.start_date,
            file_url: task.file_url ?? "",
            priority: task.priority,
            status: task.status,
          });


<Form
          onSubmit={submit}
          encType="multipart/form-data"
>
        <FileInput
                           name="file_url"
                           accept=".zip, .rar"
                           ref={inputRef}
                           onChange={handleFiles}
                           className="mt-1 block w-full rounded-2xl"
                           uploadedfile={
                                            data.file_url
                                                ? data.file_url
                                                : "No file chosen"
                                        }
           />
</Form>

I tried to modify based on what you gave me to read on the inertia documentation about multipart limitations, but I keep getting the error in the console: post is not defined

Sinnbeck's avatar

@Emokores If you want to just use post() you need to use the form helper. It has a post method.. Their example is using Inertia.post

Inertia.post(route("resources.tasks.update", task.id), {
            __method: "put",
            file_url: data.file_url,
        });
Emokores's avatar

@Sinnbeck This is what I get in the console: Uncaught TypeError: _inertiajs_inertia__WEBPACK_IMPORTED_MODULE_4__.post is not a function

Sinnbeck's avatar

@Emokores are you perhaps using vue? I was only guessing, and the example used the react implementation I went with that. Vue3 is like this I believe

this.$inertia.post(route("resources.tasks.update", task.id), {
            __method: "put",
            file_url: data.file_url,
        });
Emokores's avatar

@Sinnbeck I'm using ReactJS. So that means I do not need the form helper if I'm using Inertia.post()?

Sinnbeck's avatar

@Emokores Ah perhaps you didnt import it then?

import {Inertia} from '@inertiajs/inertia'

If it still does not work, then can you show me the version that works, vs this one that does not? They should be 100% the same except, __method: "put",

Sinnbeck's avatar

@Emokores

If it still does not work, then can you show me the version that works, vs this one that does not? They should be 100% the same except, __method: "put",

Emokores's avatar

@Sinnbeck So I changed my code to this below and removed the form helper. However, I get this error in the console Uncaught TypeError: Cannot read properties of undefined (reading 'task_name').


const { data, setData } = useState({
            id: task.id,
            task_name: task.task_name,
            due_date: task.due_date,
            start_date: task.start_date,
            file_url: task.file_url ?? "",
            priority: task.priority,
            users: assignees,
            status: task.status,
        })

Inertia.post(route("resources.tasks.update", task.id), {
            __method: "put",
            file_url: data.file_url,
        });

Sinnbeck's avatar

What line throws that error? I assume task is an object, as task.id works

Sinnbeck's avatar

You originally said

The store() method works fine.

So cant you use the code from back then and just add __method: "put",?

Emokores's avatar

@Sinnbeck I have tried to revert the code but I get the error from the backend: The POST method is not supported for this route. Supported methods: PATCH. even after using the {__method: "put"}


post(route("resources.tasks.update", task.id), {
            __method: "put",
            file_url: data.file_url,
        });

Emokores's avatar

@Sinnbeck I have figured it out. I had to register the $route->put() method in my web.php. This is what I ended up with:


Inertia.post(`/resources/tasks/${data.id}`, {
      _method: "put",
      //the rest of the fields here...
});

You gave me the eye-opener from the docs. That's what ignited my thinking cap! Thanks!

Please or to participate in this conversation.