Search code examples
javascriptphplaravellaravel-livewire

Livewire property is null when value updated through php


I have a very simple livewire component

class Test extends Component
{

    public $test = "test";

    public function submit()
    {
        dd($this->test);
    }

    public function render()
    {
        return view('livewire.test');
    }
}

and view

<div>
    <form wire:submit.prevent="submit" method="post">
        <input type="text" wire:model="test" id="test">
        <button type="button" id="ok">ok</button>
        <button type="submit">submit</button>
    </form>
    <script>
        const button = document.getElementById('ok');
        button.addEventListener('click', function() {
            const input = document.getElementById('test');
            input.value = "Test";
        });
    </script>
</div>

I simplified the code for illustrative purposes to show that JavaScript changes a value.

When I click ok what changes the value from test to Test and then submit, I get test shown instead of Test.

I except to see Test. What am I doing wrong?

It seems that the Livewire Component is not recognising the change from the Javascript code, as the following function doesn't fire either:

public function updatedTest()
{
   dd("Fired");
}

Solution

  • What @Peppermingtology said isn't entirely true. He is right that it is not the preferred way of handling Livewire, but sometimes you can't escape it.

    You can indeed use AlpineJS and that will solve your issue, but you can also cast a normal change event. Your Livewire variable isn't updating because Livewire has not detected any change. That's because programattically updated inputs don't trigger any event by default to prevent infinite event loops.

    If you simply add an event, it should also work:

    const input = document.getElementById('test');
    input.value = "Test";
    let event = new Event('change', {bubbles: true});
    input.dispatchEvent(event);