Child component doesn't update on parent change

Hi guys! I’m pretty new to Livewire and I need a little help to understand what I’m doing wrong.

I’ve created three components: CarIndex, CarEdit and a generic InputAutocomplete which helps me to populate some field. The CarIndex component show a list of cars and the CarEdit component is used to update the model Car.

<!-- CarIndex -->
<table>
    <tr>
        <th>Actions</th>
    </tr>
    <tr>
        <td>
            <span wire:click="$emit('updatingCar', {{ $car->id }})">Edit</span>
        </td>
    </tr>
</table>

As you can see, when I click on the Edit action I’m updating the current Car in CarEdit component.

class CarEdit extends Component
{
    public Car $car;

    protected $listeners = ['updatingCar' => 'setCarModel'];

    public function setCarModel(int $id): Car
    {
        return $this->car = Car::findOrFail($id);
    }
}

Now, the InputAutocomplete helps me to populate the car owner field, just like a Multiselect, Typeahead, etc. etc. And it should accept the current car owner as default value.

<!-- CarEdit -->
<section>
    ...Other inputs
    <livewire:input-autocomplete :selected="$car->owner"></livewire:input-autocomplete>
</section>

What I’m trying to achieve is that when I click on the action Edit in CarIndex the :selected="$car->owner" is updated accordingly in InputAutocomplete. I know that docs state that “Nested components CAN accept data parameters from their parents, HOWEVER they are not reactive like props from a Vue component”, but I’m wondering if there’s a workaround. I guess an $emitDown event - in order to target only the child component - would solve this case.

Let me know, and thanks!
Matteo.

If you can trigger some kind of component refresh at the CarIndex level, it should trickle down and force the :selected field to update. Although you already have a listener on your CarEdit for updatingCar. You can just emit or emitTo and raise the updatingCar event from the input-autocomplete. That should trigger a component refresh.

$this->emit('updatingCar', $car->id); should cause the CarEdit component to refresh itself.

Hi Shortbrownman,

Thanks for your reply! The issue is that it seems to not refresh. I’ve other inputs on CarsEdit component, and those fields are updated accordingly when “updatingCar” event is emitted. Everything is updated, but the InputAutocomplete component…

I try to simplify the example to better explain my issue. Let’s say I have this two components:

The ShowCarBrand component.

class ShowCarBrand extends Component
{
    public Car $car;

    public function render()
    {
        return view('livewire.show-car-brand');
    }
}
------------------------------------------
<div>
    <span>Brand: {{ $car->brand }}</span>
</div>

And the ShowCar component.

class ShowCar extends Component
{
    public Car $car;

    protected $listeners = ['showingCar' => 'setCarModel'];

    public function setCarModel(int $id)
    {
        $this->car = Car::findOrFail($id);
    }

    public function render()
    {
        return view('livewire.show-car');
    }
}
------------------------------------------
<div>
    <span>Model: {{ $car->model }}</span>
    <livewire:show-car-brand :car="$car"></livewire:show-car-brand>
</div>

What I’m trying to achieve is that when the event showingCar is fired and the ShowCar component is updated, the child component ShowCarBrand will update accordingly. Also, only the ShowCarBrand child of ShowCar should update, because I’d like to use the ShowCarBrand somewhere else in the page.

Obviously this is an oversimplified example, but I hope this better explain my issue.

Thanks!
Matteo.

Hi Guys,

Remul on StackOverflow suggested to add key="{{ $car->id }}" attribute on InputAutocomplete, that makes the component reactive to parent changes. You can read a bit more about suggested solution here and here.

Thanks,
Matteo.

1 Like