ACH's avatar
Level 1

"'legacy_model_binding' => true" not fully compatible in Livewire 3?

I have migrated an app from Livewire 2 to Livewire 3.

I have a form blade with som input fields and possibility to search and retrieve a record like this:

...
	<x-slot name="form">
                        <div class="col-span-6 sm:col-span-4">
                            <div>
        						<x-jet-label for="requestId" value="{{ __('Customer req. id:') }}" /> 
                        		<x-jet-input id="requestId" class="block mt-1 w-full" wire:model="responseCase.requestId" type="text" name="requestId" :value="old('requestId')" required autofocus autocomplete="requestId" />
                        		<x-jet-input-error for="requestId" class="mt-2" />
                    		</div>
                    		<div class="mt-4">
								<x-jet-label for="case_ref" value="{{ __('Case ref:') }}" /> 
                        		<x-jet-input id="case_ref" class="block mt-1 w-full" wire:model="responseCase.case_ref" type="text" name="case_ref" :value="old('case_ref')" required autofocus autocomplete="case_ref" />
                        		<x-jet-input-error for="responseCase.case_ref" class="mt-2" />
                    		</div>
                    		
                    		<button wire:click="getByCaseRef()"
                            	class="inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 active:bg-gray-900 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray disabled:opacity-25 transition ease-in-out duration-150">
                            	Search
                            </button>
...

In the Livewire controller, using model binding, I have the following getByCaseRef() (after migrating emit to `dispatch):

...
class RCForm extends Component
{
    use AuthorizesRequests;
    use MyLog;
    
    protected $listeners = ['ipImported'];
    
    public ResponseCase $responseCase;

	public function getByCaseRef()
    {
        $this->authorize('export', $this->responseCase);
        $rc=ResponseCase::where('case_ref', $this->responseCase->case_ref)
                                            ->orderByDesc('updated_at')
                                            ->first();
        if(isset($rc)) {
            self::uaRcLog(LogType::Info, __CLASS__, $rc, "Search executed successfully");
            if (foo))
                $this->isIpImported = true;
            else 
                $this->isIpImported = false;
                $this->rcSearchTriggered=true;
                $this->dispatch('rcFound');
                $this->responseCase=$rc;
        }
        else {
            self::uaLog(LogType::Info, __CLASS__, "Search executed but no records found");
            $this->rcSearchTriggered=true;
            $this->dispatch('rcNotFound');
        }
    }
...

Before migrating to Livewire 3, after performing a search these fields were auto populated. After migration to Livewire 3 the search still works but the fields do not get auto populated. The documentation for Livewire says:

By setting legacy_model_binding to true, Livewire will handle Eloquent model properties exactly as it did in version 2.

Is this a bug in Livewire 3, have I tweaked the Livewire 2 functionality beyond compatibility or what?

0 likes
5 replies
ACH's avatar
Level 1

I have started moving away from legacy model binding and turned this off in config/livewire.php. Still nothing is displayed. I even tried adding value="{{ foo }}" (eg foo=requestId) and see the correct value when I inspect this in the browser but Livewire surpresses this when I use wire:model="foo" it seems so the value is not displayed.

When doing the inspection in the browser I notice he following type of warnings and error messages:

Alpine Expression Error: Cannot read properties of undefined (reading 'on')

Expression: "window.Livewire.find('3rt3PHqmFqHIbstvP0kj').on('rcFound', () => { clearTimeout(timeout); shown = true; timeout = setTimeout(() => { shown = false }, 2000);  })"

And corresponding (I assume) error message:

app.8c8ff37e.js:36 Uncaught TypeError: Cannot read properties of undefined (reading 'on')
    at [Alpine] window.Livewire.find('3rt3PHqmFqHIbstvP0kj').on('rcFound', () => { clearTimeout(timeout); shown = true; timeout = setTimeout(() => { shown = false }, 2000);  }) (eval at <anonymous> (http://localhost:8000/build/assets/app.8c8ff37e.js:36:670), <anonymous>:3:76)

In Safari I also see this error message:

TypeError: null is not an object (evaluating 'carry[i]')

The on type of error message seem to be related to some event dispatching I do but seem not to be related to the problem described above (but explains why these events are not handled properly). Could it be related?

ACH's avatar
Level 1

I notice that I have 2 versions of Livewire.js in the application folder:

  1. public/vendor/livewire.js. Date: jun 2023
  2. vendor/livewire/livewire/dist/livewire.js. Date: feb 2024

I am guessing that the public one is outdated. I run npm run build at some point. May be I should not have? How can I fix this?

ACH's avatar
Level 1

I tried to run php artisan livewire:publish --assets but then get message INFO No publishable resources for tag [livewire:assets]. .

I renamed public/vendor/livewire to .../livewire-bak. This did not help.

composer show -D reports livewire/livewire v3.4.6 A front-end framework for Laravel.

ACH's avatar
Level 1

I found out that I used an old version of Jetstream, which was not compatible with Livewire 3, so I upgraded Jetstream to ver 4.2. Unfortunately this did not help.

1 like
ACH's avatar
ACH
OP
Best Answer
Level 1

Resolved by removing (commenting out) Alpine stuff from resources/app/app.js:

import './bootstrap';

//import Alpine from 'alpinejs';

//window.Alpine = Alpine;

//Alpine.start();

And then running npm run build

1 like

Please or to participate in this conversation.