Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

stefanp's avatar

Photos sent from vue to laravel backend are in blob format

Hi, I have the following situation and I do not know how to manage it.

In my vue3 I have this Inertia form

let form = useForm({
  name: props.product.name,
  description: props.product.description,
  photos: store.getPhotos,
});

and somewhere below I submit it like so:

function submit() {
  form.post(route('products.update', { id: props.product.id }));
}

The problem is that in laravel I have all the photos in blob format and I do not know how should I use FormData with inertia and vue.

Can anyone help, please?

Thanks!

0 likes
3 replies
AungHtetPaing__'s avatar

@stefanp here is what I did in my project (installed version of vue is 3 but using vue2 syntax)

// template
<input
						ref="coverPhoto"
						@change="selectedCoverPhoto($event)"
						type="file"
						class="hidden"
					>
					<button
						v-if="!coverPhotoPreview"
						@click="$refs.coverPhoto.click()"
						type="button"
						class="bg-gray-200 border border-dashed border-gray-500 rounded-lg h-64 w-52 grid place-content-center text-gray-500 hover:text-gray-700 cursor-pointer hover:border-gray-700"
					>
						<svg
							xmlns="http://www.w3.org/2000/svg"
							class="h-10 w-10 mx-auto"
							viewBox="0 0 20 20"
							fill="currentColor"
						>
							<path
								fill-rule="evenodd"
								d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-11a1 1 0 10-2 0v2H7a1 1 0 100 2h2v2a1 1 0 102 0v-2h2a1 1 0 100-2h-2V7z"
								clip-rule="evenodd"
							/>
						</svg>
						<h1 class="text-sm px-5">
							Select book cover photo to upload
						</h1>
					</button>

// script
data() {
        return {
            form: this.$inertia.form({
                cover_photo: '',
                title: '',
                excerpt: '',
                author: '',
                price: '',
                category_id: '',
                stock_count: '',
            }),
            coverPhotoPreview: '',
            coverPhotoName: '',
            showCoverPhotoEdit: false,
        }
    },
methods: {
        submit() {
            this.form.post(route('admin.books.store'))
        },

        selectedCoverPhoto(e) {
            this.form.cover_photo = e.target.files[0]
            this.coverPhotoName = this.$refs.coverPhoto.files[0].name
            const reader = new FileReader()
            reader.onload = (e) => {
                this.coverPhotoPreview = e.target.result
            }
            reader.readAsDataURL(this.$refs.coverPhoto.files[0])
        }
    }

//controller
public function store(StoreBookRequest $request)
    {
        $request->validated();

        $attributes = $request->except('cover_photo');
        $attributes['slug'] = Str::slug($request->title . '-' . uniqid());
        $attributes['cover_photo_path'] = $request->file('cover_photo')->store('cover-photos');

        Book::create($attributes);

        return Redirect::route('admin.books.index');
    }
stefanp's avatar

I think I know what is going on and I ask you to validate may thoughts.

I use this code which helps me to preview the image. I pass all files to addFiles method and within the addfiles method I process them witin UploadFile class (pretend you don’t see line 22) to prepare more data for the frontend.

It seems that I can preview the photo based on line 17. I do not want to save the photo and then see it. I want to see it first and after that to send it to laravel backend.

Also in addFiles(), I add the photos to my store - line 9.

For sending my form to laravel I use this piece of code and my laravel request looks like image_3 where my problem arises.

Well… finally I realised that i do not have to send the photo in blob format but in a file File object and for this I added the line 22 in the UploadableFIle class and now my request looks better like in image_4

What do you think about my version?

I try to include photos from imgur but I do not know why is not working so I will post the code below:

import { useStore } from "@/Stores/pinia";

export default function () {
  const store = useStore();

  function addFiles(newFiles) {
    let newUploadableFiles = [...newFiles]
    .map((file) => new UploadableFile(file));
    store.addPhotos(newUploadableFiles);
  }
  return { addFiles };
}

class UploadableFile {

  constructor(file) {
    this.id =  Math.floor(Math.random() * (1000000 - 10000) + 1000000);   //todo: alta varianta de a da un id pozei pentru a o putea sterge
    this.blob = URL.createObjectURL(file);
    this.is_new = true;
    this.is_packaging = 0;
    this.original_name = file.name;
    this.request_front_deletion = false;
    this.file_obj = new File([URL.createObjectURL(file)], file.name);  !! this is line 22
  }
}
let form = useForm({
  name: props.product.name,
  description: props.product.description,
  photos: store.getPhotos,
});

function submit() {
  form.post(route('products.update', { id: props.product.id }));
  // Inertia.post(route('products.update', {id: props.product.id}), form, {forceFormData: true});
}
array:3 [▼ // app/Http/Controllers/ProductController.php:103
  "name" => "nume p"
  "description" => "desc p"
  "photos" => array:6 [▼
    0 => array:14 [▶]
    1 => array:14 [▶]
    2 => array:14 [▶]
    3 => array:7 [▼
      "id" => "1816946"
      "blob" => "blob:http://prefix.test/5965a27a-0ee6-44e1-8fee-c504c32110b3"
      "is_new" => "1"
      "is_packaging" => "0"
      "original_name" => "category-page-04-image-card-03.jpg"
      "request_front_deletion" => "1"
array:3 [▼ // app/Http/Controllers/ProductController.php:103
  "name" => "nume p"
  "description" => "desc p"
  "photos" => array:6 [▼
    0 => array:14 [▶]
    1 => array:14 [▶]
    2 => array:14 [▶]
    3 => array:7 [▼
      "id" => "1816946"
      "blob" => "blob:http://prefix.test/5965a27a-0ee6-44e1-8fee-c504c32110b3"
      "is_new" => "1"
      "is_packaging" => "0"
      "original_name" => "category-page-04-image-card-03.jpg"
      "request_front_deletion" => "1"
      "file_obj" => Illuminate\Http\UploadedFile {#337 ▼
        -test: false
        -originalName: "category-page-04-image-card-03.jpg"
        -mimeType: "application/octet-stream"
        -error: 0
        #hashName: null
        path: "/tmp"
        filename: "phpcP9srG"
        basename: "phpcP9srG"
        pathname: "/tmp/phpcP9srG"
        extension: ""
        realPath: "/tmp/phpcP9srG"
        aTime: 2022-12-23 10:53:41
        mTime: 2022-12-23 10:53:41
        cTime: 2022-12-23 10:53:41
        inode: 1211465
        size: 60
        perms: 0100600
        owner: 501
        group: 20
        type: "file"
        writable: true
        readable: true
        executable: false
        file: true
        dir: false
        link: false
      }
    ]

Please or to participate in this conversation.