Mouayed Keziz
Mouayed Keziz

Reputation: 11

laravel inertia invoking the update handeler not working (with file upload)

i dont think this is a good title but imma explain my situation im using laravel with inertia, everything works fine ive never had such experiance with a framework im building a quick demo to learn this stack and made a good progress in my first day

the situation, i have a post model (title, content) where each user has many posts, each post has one image, i have my resource route set up

Route::resource('posts', PostController::class)->middleware(['auth']);

everything works fine except updating a post, when updating the title and content it works, but when updating the image i got validation error for the title and content which is weird

 public function update(Request $request, Post $post)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'content' => 'required|string',
            'image' => 'nullable|image|mimes:jpg,jpeg,png,gif,svg|max:2048'
        ]);

        $data = $request->only('title', 'content');

        if ($request->hasFile('image')) {
            if ($post->image_path) {
                Storage::disk('public')->delete($post->image_path);
            }
            $data['image_path'] = $request->file('image')->store('images', 'public');
        }

        $post->update($data);

        return redirect()->route('posts.show', $post);
    }

in the client side im submitting the form using inertia's useform hook

 const { data, setData, put, processing, errors } = useForm({
        title: post.title,
        content: post.content,
        image: null,
    });

    const handleSubmit = (e) => {
        e.preventDefault();
        put(route("posts.update", post));
    };

tried using patch instead of put (not working)

i tried using forceFormData (not working)

    const handleSubmit = (e) => {
        e.preventDefault();
        put(route("posts.update", post), {forceFormData : true});
    };

i tried using form data (not working)

    const handleSubmit = (e) => {
        e.preventDefault();
        const formData = new FormData();
        formData.append("title", data.title);
        formData.append("content", data.content);
        if (data.image) {
            formData.append("image", data.image);
        }
        patch(route("posts.update", post.id), { forceFormData: true });
    };

note : i made sure the data (from useForm) has the correct data (title, content and image) and the issue isnt in collecting data from the client, also im new to laravel and php and this may sound stupid but i didnt find a way to print/echo the comming data to the server so i can make sure its the correct data im expecting

Upvotes: 1

Views: 302

Answers (2)

kdan
kdan

Reputation: 113

Here are 3 solutions:

const { data, setData, post, errors, processing } = useForm({
    title: currentPost.title,
    body: currentPost.body,
    image: null,
  });

  const errorsActive = errors;

  const route = useRoute();

  function submit(e) {
    e.preventDefault();
    // Option 1, needs a post route in web.php
    // post(route("posts.update", currentPost.id));

    // Option 2, needs a post route in web.php
    // post(`/posts/${currentPost.id}`);
    
    // Option 3
    router.post(route("posts.update", currentPost.id), {
      _method: "PUT",
      title: data.title,
      body: data.body,
      image: data.image,
    });
  }

Upvotes: 0

Subha
Subha

Reputation: 1623

everything works fine except updating a post, when updating the title and content it works, but when updating the image i got validation error for the title and content which is weird

It is quite obvious as per the code you have written. Because you have for force validation to these fields i.e. title & content. So when you update only the image field by default you get validation error for the title and content which is not weird at all.

In order to update any of the fields independently and avoid validation issues , use sometimes that apply validation rules only when the field is present in the request like this.

$request->validate([
            'title' => 'sometimes|required|string|max:255',
            'content' => 'sometimes|required|string',
            'image' => 'nullable|image|mimes:jpg,jpeg,png,gif,svg|max:2048'
        ]);

Try this it will work for sure if your image-uploading code & storage:link path properly initiated.

To know in details about sometimes validation rule you can check the link given below.

https://laravel.com/docs/11.x/validation#validating-when-present

Upvotes: 0

Related Questions