vincent15000's avatar

Upgrade from Livewire 2 to Livewire 3

Hello,

I'm upgrading an old personal project.

And I have this problem.

It's my Entreprise select component.

    <select id="entreprise_id" wire:model.live="entreprise_id" name="entreprise_id" @if ($readonly) disabled @endif>
        <option value="">Choisir une entreprise</option>
        @foreach ($entreprises as $entreprise)
            <option value="{{ $entreprise->id }}">{{ $entreprise->raison_sociale }}</option>
        @endforeach
    </select>

It worked fine with Livewire 2, but with Livewire 3 the option isn't initialized.

I have checked the value of $entreprise_id and it's the right one.

Any idea ?

Thanks for your help.

V

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

Certainly! This is a common issue when upgrading from Livewire 2 to Livewire 3, due to changes in how Livewire syncs data and refreshes the DOM.

The Issue

In Livewire 3, the modifier .live was removed and is no longer needed (wire:model.live). Additionally, Livewire 3 now expects you to use wire:model, unless you have a very specific use-case that needs .defer or .lazy.
However, another change is that Livewire now closely follows how Alpine handles reactivity, and the browser's <select> may not always behave as expected if the value types differ (string versus int).


Solution Steps

  1. Remove .live Modifier

    Replace:

    wire:model.live="entreprise_id"
    

    With:

    wire:model="entreprise_id"
    
  2. Ensure Type Consistency

    Make sure the value of each <option> is the same type as your $entreprise_id property (string or int), and that the $entreprise_id property is properly set in your Livewire component before rendering the select. You may want to cast the values:

    <option value="{{ (string) $entreprise->id }}">{{ $entreprise->raison_sociale }}</option>
    

    And in your Livewire component:

    public int|string|null $entreprise_id = null;
    
  3. If Using defer or lazy, Check for Delays

    If you intentionally want to delay updates, use wire:model.defer or wire:model.lazy appropriately.


Example — Updated Select

<select id="entreprise_id" wire:model="entreprise_id" name="entreprise_id" @if ($readonly) disabled @endif>
    <option value="">Choisir une entreprise</option>
    @foreach ($entreprises as $entreprise)
        <option value="{{ (string) $entreprise->id }}">{{ $entreprise->raison_sociale }}</option>
    @endforeach
</select>

Extra tip: If $entreprise_id is an integer, casting the value to string ensures the browser matches the value correctly.


TL;DR

  • Remove .live: use wire:model instead.
  • Cast option values to string if your model uses integer IDs.
  • Ensure $entreprise_id is set before rendering.

If you still experience issues, try running php artisan livewire:publish --assets and clear your browser cache to ensure the new Livewire 3 assets are being loaded.


Let me know if this works or if you have further issues!

1 like

Please or to participate in this conversation.