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

valentin_vranic's avatar

Livewire #[Modelable] does not seems to work

Hi all! I'm trying to use #[Modelable] and I'm curios how to use it for select, or my scenario

So my approach is to open up a dialog (livewire component), there select couple of things, and when close the dialog then to update select options in parent blade.

Well, bcs I don't want to re-render, the modal after property update, I dispatch an event on each select change event and update the property, which is binded to the parent. However it's not working..

$wire.dispatch('setNumbers', [selectedValues]);

    #[Modelable]
    public $numbers;

    #[Renderless]
    #[On('setNumbers')]
    public function setNumbers(array $numbers): void
    {
        $this->numbers = $numbers;
    }

And in my parent view, it looks like this

<div class="col-md-4 text-end" wire:show="form.isAuthorizedVisible">
    <select id="numbers" class="form-select mb-2">
        @foreach($form->numbers as $number)
            <option value="{{$number}}">{{ $number }}</option>
        @endforeach
    </select>
    <livewire:manage-cli wire:model="form.numbers"/>
</div>
0 likes
2 replies
LaryAI's avatar
Level 58

To address the issue you're facing with the #[Modelable] attribute in Livewire, let's go through a few steps to ensure everything is set up correctly.

Understanding the Problem

You want to update a select element in a parent component when a dialog (Livewire component) is closed. You're using the #[Modelable] attribute to bind data between components and dispatching an event to update the parent component's property.

Solution Steps

  1. Ensure Correct Event Dispatching: Make sure that the event is being dispatched correctly from the child component. The $wire.dispatch method should be used within a Livewire component's JavaScript context. Ensure that the event name and data are correct.

  2. Check Event Listener: Verify that the #[On('setNumbers')] attribute is correctly set up to listen for the setNumbers event. The method setNumbers should be public and should correctly update the $numbers property.

  3. Ensure Property Binding: Make sure that the property binding in the parent component is correctly set up. The wire:model directive should be used to bind the property to the Livewire component.

  4. Update the Parent Component: Ensure that the parent component is correctly listening for changes to the $numbers property and that the select options are being updated accordingly.

Example Code

Here's a refined version of your setup:

Child Component (Dialog):

class ManageCli extends \Livewire\Component
{
    #[Modelable]
    public $numbers;

    public function updatedSelectedValues($selectedValues)
    {
        $this->dispatchBrowserEvent('setNumbers', ['numbers' => $selectedValues]);
    }
}

Parent Component:

class ParentComponent extends \Livewire\Component
{
    #[Modelable]
    public $numbers = [];

    #[On('setNumbers')]
    public function setNumbers(array $numbers): void
    {
        $this->numbers = $numbers;
    }

    public function render()
    {
        return view('livewire.parent-component', [
            'numbers' => $this->numbers,
        ]);
    }
}

Parent Blade View:

<div class="col-md-4 text-end" wire:show="form.isAuthorizedVisible">
    <select id="numbers" class="form-select mb-2">
        @foreach($numbers as $number)
            <option value="{{ $number }}">{{ $number }}</option>
        @endforeach
    </select>
    <livewire:manage-cli wire:model="numbers"/>
</div>

Additional Tips

  • Debugging: Use dd($numbers) in the setNumbers method to ensure the data is being received correctly.
  • JavaScript Console: Check the browser's console for any JavaScript errors that might indicate issues with event dispatching.
  • Livewire Version: Ensure you are using a version of Livewire that supports the #[Modelable] and #[On] attributes.

By following these steps and ensuring the setup is correct, you should be able to update the select options in the parent component when the dialog is closed.

valentin_vranic's avatar
valentin_vranic
OP
Best Answer
Level 5

Well couple of notes, while I've figured out my way, and what's working, and what's not!

  1. I was replacing to wire:model.live, because that forces the updated property to "update" and re-render the view when using #[Modelable]
  2. Another obvious thing to use :key on lw components, to preserve it
  3. Don't use #[Lazy] PHP attribute when your modal is an lw component
  4. Because I'm having couple of conditional show/hides, I figured out that the new wire:show would not trigger the mount method of the initialized component, rather use @if() @endif

Maybe I'm wrong in some scenarios, but those helped me, and hope will help to someone too.

Please or to participate in this conversation.