Rretzko's avatar
Level 15

Livewire v3 wire:model not updating

Hi - I have a simple form that correctly displays the wire:model value but does not update it on change and I see no network traffic when I change the value. I've gotten something wrong and appreciate your eyes on this! Main Blade file

<x-layouts.livewire.teachers breadcrumbsFor="schoolsAdd" unreadCount="0"  >

    <div class="bg-white text-gray-800 rounded-lg">

        <livewire:teachers.schools.school-component :dto="$dto" />

    </div>

</x-layouts.livewire.teachers>

school-component blade file

<div class="p-2">

     <form  class="bg-gray-100 border border-black p-2 w-11/12 mx-auto rounded-lg">

         @csrf

         <h2 class="text-lg font-semibold capitalize mb-2">Add School</h2>

         <input wire:model="postalCode"  type="text" />
		
{{-- Used for testing to confirm $postalCode value and correctly displays "00000" --}}
         PostalCode: @json($postalCode)

     </form>
</div>

Livewire Component

<?php

namespace App\Livewire\Teachers\Schools;

use App\Models\Geostate;
use App\Models\Teachers\County;
use Livewire\Attributes\Validate;
use Livewire\Component;

class SchoolComponent extends Component
{
    public array $dto;

    #[Validate(['required','min:1','max:16'])]
    public string $postalCode = "00000";

    public function render()
    {
        return view('livewire..teachers.schools.school-component');
    }

    /**
     * @return void
     */
    public function updatedPostalCode():void
    {
//This method is never hit
        if(strlen($this->postalCode) > 2){

//for testing
            dd($this->postalCode);
        }
    }

}

Thanks for your assistance! Rick

0 likes
3 replies
LaryAI's avatar
Level 58

It seems like you've encountered an issue with Livewire not updating the postalCode property when the input changes. Here are a few steps to troubleshoot and resolve the issue:

  1. Ensure Livewire Scripts are Loaded: Make sure that you have included the Livewire scripts in your main layout file. Without these scripts, Livewire won't be able to send Ajax requests to update the state on the server.
<!-- At the end of your body tag -->
@livewireScripts
  1. Check for JavaScript Errors: Open your browser's developer console and check for any JavaScript errors that might be preventing Livewire from functioning correctly.

  2. Remove @csrf: Livewire handles CSRF protection for you, so you don't need to include @csrf in your Livewire forms. This could potentially cause issues.

  3. Namespace in View Path: There seems to be a typo in the namespace of the view path in your render method. The double dots .. might be causing the view not to be found correctly. It should be a single dot.

public function render()
{
    return view('livewire.teachers.schools.school-component');
}
  1. Check for Naming Conflicts: Ensure that there are no JavaScript variables or other elements on the page that might conflict with the Livewire component's properties.

  2. Validate Attribute: The #[Validate] attribute you're using is not a standard Livewire or PHP attribute. Livewire has its own validation system, which you can use within a method like so:

use Livewire\Component;
use Illuminate\Validation\Rule;

class SchoolComponent extends Component
{
    public $postalCode = "00000";

    protected function rules()
    {
        return [
            'postalCode' => ['required', 'min:1', 'max:16'],
        ];
    }

    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }

    // ...
}
  1. Check Livewire Version: Ensure that you are using Livewire v3 as you mentioned in the question title. If you are on an older version, the syntax might differ.

  2. Clear Cache: Sometimes, Livewire can behave unexpectedly due to caching issues. Try clearing your application cache:

php artisan cache:clear
php artisan view:clear
  1. Debugging: If the updatedPostalCode method is not being hit, you can try using Livewire's updated lifecycle hook to see if any property updates are being detected:
public function updated($propertyName)
{
    info("Updated property: " . $propertyName);
}
  1. Livewire Component Tag: Ensure that the Livewire component tag in your Blade file matches the registered component name. If you've used a different name when registering the component, it should match exactly.

After making these changes, if you're still facing issues, try to simplify the component to the bare minimum to isolate the problem. You can also reach out to the Livewire community or consult the Livewire documentation for further assistance.

Rretzko's avatar
Level 15

@LaryAI I tried each of these suggestions and the problem persists. I'm sure this is something fundamental, but I can't see it!

Rretzko's avatar
Rretzko
OP
Best Answer
Level 15

Hi - I reloaded this using the example on the Livewire documentation and included the $postalCode variable. The counter components work as expected, but I get no visual update on the form when I change the $postalCode. However, when I increment/decrement the $counter, then the page re-renders and displays the changed $postalCode value on the form! On my Network tab I can see that changing the $postalCode generates no activity, but clicking the increment/decrement buttons generates two update actions; one for the $postalCode and the second for the $counter. This led me to add .live to the wire:model (i.e. wire:model.live="postalCode") which then caused the form to work as expected. I'll do more reading on the documentation, but my takeaway is that form elements now default to delaying action until submitted unless the .live suffix is added. I wanted to document this in case someone else hits this and would appreciate any wiser thoughts! Thanks - Rick

create.blade

<x-layouts.teachers breadcrumbsFor="schoolsAdd" unreadCount="0"  >

    <div class="bg-white text-gray-800 rounded-lg">

        <livewire:counter />
      
    </div>

</x-layouts.teachers>

counter.blade

<div>
    <h1>{{ $count }}</h1>

    <button wire:click="increment">+</button>

    <button wire:click="decrement">-</button>

    <div>PostalCode: {{ $postalCode }}</div>
    <input wire:model.live="postalCode" type="text" />
</div>

Counter.php component

<?php

namespace App\Livewire;

use Livewire\Component;

class Counter extends Component
{
    public $count = 1;

    public $postalCode = "00000";

    public function increment()
    {
        $this->count++;
    }

    public function decrement()
    {
        $this->count--;
    }
    public function render()
    {
        return view('livewire.counter');
    }

    public function updated($propertyName): void
    {
        info($propertyName . ' has been updated.');
    }
}

1 like

Please or to participate in this conversation.