Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to upload files with inertia js and laravel 8.0

I have an update ( patch form ) that can have some basic fields with one featured image and an array of gallery images.

updatePhotoPreview(event) {
   this.featuredImagePreview = URL.createObjectURL(event.target.files[0])
   this.updateProductForm.featured_image = event.target.files[0]
},

Before sending the request and even in the request header, the featured image is File and binary.

Then I'm simply posting the form with this.form.patch(url).

I'm getting an error the featured_image must be an image.

I've dumped the request and somehow my featured_image value has beenenter image description here set to an empty array.

The same is for the gallery images, it has been turned into an array of empty arrays.

I've tried changing the route to post, put, the result is the same, I've added a custom header

 { headers: {'Content-Type': 'multipart/form-data'} }

The result is the same.

but the same form is working for the create endpoint of this resource with POST method. I've removed all the request classes and dumping with request()->all()

How can I fix this?

like image 485
Aryan Ahmed Anik Avatar asked Oct 08 '20 18:10

Aryan Ahmed Anik


People also ask

What is inertia JS in Laravel?

Inertia is a small library that allows you to render single-file Vue components from your Laravel backend by providing the name of the component and the data that should be hydrated into that component's "props".

What is inertia JS used for?

Inertia. js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.


2 Answers

It's possible to upload a photo via InertiaJS and Laravel 8 following the steps below:

  1. In our VueJS component's HTML:
<input type="file" class="hidden"
             ref="photo"
             @change="updatePreview">
<div v-show="preview">
  <span class="block w-20 h-20 rounded-full"
        :style="'width: 5rem; height: 5rem; border-radius: 999px; display: block; background-size: cover; background-repeat: no-repeat; background-position: center center; background-image: url(\'' + photoPreview + '\');'">
  </span>
</div>
  1. In our methods object:
updatePhotoPreview() {
    const reader = new FileReader();

    reader.onload = (e) => {
        this.preview = e.target.result;
    };

    reader.readAsDataURL(this.$refs.photo.files[0]);
},
storePhoto() {
    if (this.$refs.photo) {
        this.form.photo = this.$refs.photo.files[0]
    }

    this.form.post(route('photo.store'), {
        preserveScroll: true
    });
},
  1. In our data function:
data() {
   return {
       form: this.$inertia.form({
           '_method': 'PUT',
           photo: null,
       }, {
           resetOnSuccess: false,
       }),
       preview: null,
   }
},
  1. In our Laravel Controller:
class PhotoController 
{
    public function store(array $input)
    {
        Validator::make($input, [
            'photo' => ['nullable', 'image', 'max:1024'],
        ]);

        if (isset($input['photo'])) {
           $photo->storePublicly();
        }
    }
}
like image 157
Stefano Amorelli Avatar answered Oct 22 '22 12:10

Stefano Amorelli


I fix this by adding '_method' on form and using 'post' request.

data() {
    return {
        form: this.$inertia.form({
            _method: "PUT",
        })
    };
},
methods: {
    submit(form) {
        this.form
            .post("route/id", form, {
                preserveState: true
        })
    }
}
like image 2
chojisan Avatar answered Oct 22 '22 10:10

chojisan