1

Weird issue with my Livewire: the validation, when I send a file, always fails on the first time. If I have the criteria that it must be a pdf, I will put the PDF, submit the form, get a message telling me I have the wrong format, I won't change anything, resubmit and it will go through with no issue.

Does anyone knows why it might be happening?

<?php

namespace App\Http\Livewire\Branch\Documents;

use App\Models\BranchDocument;
use Livewire\Component;
use Livewire\WithFileUploads;

class Upload extends Component
{
    use WithFileUploads;

    public BranchDocument $document;
    public $file;
    public $saved = false;

    public function render()
    {
        return view('livewire.branch.documents.upload');
    }

    public function save() {
        $this->validate([
            'file' => 'mimes:jpg,bmp,png,pdf|max:10240', // 1MB Max
        ]);

        $this->document->file = $this->file;

        $this->saved = true;
    }
}
<div x-data="{ open: false }">
    <li class="@if(!$saved) hover:bg-gray-100  py-2 px-2 rounded cursor-pointer @endif" @click="open = true">
        <div class="relative">
          <div class="relative flex space-x-3">
            <div class="min-w-0 flex-1 flex justify-between space-x-4 items-center">
              <div>
                <p class="text-sm text-porange">{{ $document->document_type->title }}@if($saved)<span class="text-sm text-gray-600"> - {{ __('Document sent!') }}</span>@endif</p>
                <p class="text-xs text-gray-600">{{ $document->created_at->diffForHumans() }}</p>
              </div>
                <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600" fill="none" viewBox="0 0 24 24" stroke="currentColor" >
                    @if(!$saved)
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
                    @else
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                    @endif
                </svg>
            </div>
          </div>
        </div>
      </li>

      @if(!$saved)
      <div x-show="open" class="fixed z-10 inset-0 overflow-y-auto" aria-labelledby="modal-title" role="dialog" aria-modal="true">
        <div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
          <!--
            Background overlay, show/hide based on modal state.

            Entering: "ease-out duration-300"
              From: "opacity-0"
              To: "opacity-100"
            Leaving: "ease-in duration-200"
              From: "opacity-100"
              To: "opacity-0"
          -->
          <div class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" aria-hidden="true"></div>

          <!-- This element is to trick the browser into centering the modal contents. -->
          <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>

          <!--
            Modal panel, show/hide based on modal state.

            Entering: "ease-out duration-300"
              From: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
              To: "opacity-100 translate-y-0 sm:scale-100"
            Leaving: "ease-in duration-200"
              From: "opacity-100 translate-y-0 sm:scale-100"
              To: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
          -->
          <div @click.away="open = false" class="inline-block align-bottom bg-white rounded-lg px-4 py-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
            <div>
              <div class="text-center">
                <h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">
                  {{ __('Upload ":title"', ['title' => $document->document_type->title])}}
                </h3>
              </div>
            </div>
            <form wire:submit.prevent="save">

            <input type="file" wire:model="file" class="file-input-business block mx-auto mt-4"/>
            @error('file') <span class="error">{{ $message }}</span> @enderror

            <div class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense">
              <button type="submit" type="button" class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-porange text-base font-medium text-white hover:bg-porange-darker focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:col-start-2 sm:text-sm">
                {{ __('Send')}}
              </button>
              <button @click="open = false" type="button" class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-porange sm:mt-0 sm:col-start-1 sm:text-sm">
                {{ __('Cancel')}}
              </button>
            </div>
        </form>
          </div>
        </div>
      </div>
      @endif
</div>

Thank you!

1 Answer 1

1

Is the file uploaded before you hit submit? If not then the file is null hence the wrong format error. Check its value in the save method before validation. You can also use wire.loading on a div to determine if the file is still uploading.

You may also run into issues with built in artisan development server (the one you start with php artisan serve command). It has different limitations to a 'real' server - upload file size, formats, etc.

Sign up to request clarification or add additional context in comments.

2 Comments

That was it! If I waited 1-2 seconds it worked. The file wasn’t uploaded and I was trying to send it. On the second try, it was uploaded so it worked.
Great! :) with wire.loading you can for example disable the submit button so no one can submit before the file is uploaded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.