Search code examples
laravellaravel-livewire

Laravel Livewire form, if validation fails, pivots don't work


I have a form made with Livewire in Laravel.

This is the Livewire controller

namespace App\Http\Livewire;

use Livewire\Component;
use App\Rules\Mobile;

class Form extends Component
{
    public $mobile;
    public $required;
    public $fields;
    public $showDropdown = true;


    public function mount()
    {
        foreach($this->fields as $field){
            $this->required[$field->name] = ($field->pivot->is_required == '1') ? 'required' : 'nullable';
        }
    }

    public function submit()
    {
        $validatedData = $this->validate([
            'mobile' => [$this->required['mobile'] ?? 'nullable', new Mobile()]
        ]);
    }
}

This is the Livewire view

<div>
    <div x-data="{ open: @entangle('showDropdown').defer, required: @js($required) }">
        <span x-show="open" wire:loading.remove>
            <form wire:submit.prevent="submit" style="display: flex; flex-direction: column;">
                <div class="fields">
                    @foreach($fields as $field)
                        <div class="form-{{$field->name}}">
                            @if($field->name == 'mobile')
                                <input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
                            @endif
                                @error($field->name) <span class="error">{{ ucfirst($message) }}</span> @enderror
                        </div>
                    @endforeach
                </div>
                    <button class="btn btn-primary">Send</button>
            </form>
        </span>
    </div>
</div>

Problem is here placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}"

When the form is first loaded $field->pivot->placeholder is set, but after I submit the form and the validation fails, it's not set anymore and $field->name is used instead of $field->pivot->placeholder

Have checked this way:

<input name="{{$field->name}}" type="tel" wire:model.defer="{{ $field->name }}" placeholder="{{ __($field->pivot->placeholder ?? $field->name) }}">
{{ var_dump(isset($field->pivot->placeholder)) }}

When the form is first loaded it prints bool(true) under the field, after I send the form it says bool(false)

How can I get over this? Why the pivot does not work after validation fails?

//Edit: Did a workaround, but I would still like to know why it happens

What I did is I used another property $placeholders

In the Livewire controller have added public $placeholders;, in the mount() have added $this->placeholders[$field->name] = $field->pivot->placeholder ?? $field->name;, and then used it in the view like placeholder="{{ __($placeholders[$field->name] ?? $field->name) }}"


Solution

  • I don't know much about livewire , but I know that mount() only called on the initial page load meaning it will only run when you refresh the whole page or visit the page. Instead of only using mount() you should also use hydrate() which will run every subsequent request after the page load.

    mount() - Initial Page Load

    hydrate() - Every subsequent request

    You can implement the hydrate() like how you implement the mount()