Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Snapey's avatar
Level 122

Livewire v3 update hook when using arrays

I'm trying to watch for a field changing in a livewire component so that some manipulation of another select can occur depending on the first value selected (cascading dropdowns).

But the form has multiple rows and so wire:model looks like $guests.$key.ticketType

When the guests array is first used it is empty. I look for updates to the field, but because it is part of an array I can't just use an updating function name that directly relates to the field.

So, updatingGuests($value, $field) is used instead.

On first change, the updating function receives;

 $value = array:1 [
  "ticketType" => "16"
]
$field =0 // the guests array index

however when the item is then in the array, and is changed, the same function receives;

$value = 15

$field = 0.ticketType

Is there a clever way I can normalise this other than just duplicating my code for the two scenarios?

0 likes
2 replies
LaryAI's avatar
Level 58

Certainly! In Livewire, when you're dealing with dynamic inputs such as arrays, you can use the updated magic method to listen for changes to any property, including array elements. However, you need to handle the different scenarios that you've described.

Here's a solution that normalizes the handling of the $value and $field parameters within the updated method:

public function updated($field, $value)
{
    // Normalize the field name and get the index and key if available
    $fieldParts = explode('.', $field);
    $index = $fieldParts[0];
    $key = $fieldParts[1] ?? null;

    // If the key is not set, we're dealing with the first scenario
    if (is_null($key)) {
        $key = 'ticketType';
        $value = $value[$key];
    }

    // Now you have a normalized $index and $key, and you can manipulate other fields
    if ($key === 'ticketType') {
        // Perform your manipulation here
        $this->updateRelatedSelect($index, $value);
    }
}

private function updateRelatedSelect($index, $ticketType)
{
    // Your logic to manipulate the related select based on the ticket type
    // For example, you might want to update another array in your component
    $this->guests[$index]['relatedField'] = $this->calculateRelatedValue($ticketType);
}

private function calculateRelatedValue($ticketType)
{
    // Your logic to calculate the related value
    // This is just a placeholder for your actual logic
    return $ticketType * 10; // Example calculation
}

In this solution, we first normalize the $field by splitting it into parts. If the $key is not set, it means we're dealing with the first scenario where $value is an array. We then extract the actual value from this array.

After normalization, we can use the $index and $key to perform any manipulation we need. The updateRelatedSelect method is a placeholder for whatever logic you need to apply when the ticketType changes.

This approach avoids duplicating code for the two scenarios and keeps the update logic centralized and easier to maintain.

brunopincaro's avatar

I don't know if I quite understood your question but I think that I was confronted with something similar and my solution was to use a property name pattern to check if it matched the wire:model.

Maybe something like this will suite your need:

public function updated($property, $value)
{
	// This pattern matches strings like "guests.123.ticketType"
    if (preg_match('/^guests\.([^.]+)\.ticketType$/', $property, $matches)) {
        $key = $matches[1]; // Captures the dynamic key/index for the guest
		$ticketType = $value;
}

You'll might need to dump the $property to check for what livewire is looking. It might be looking for "$guests.$key" and in that case your pattern will be:

// This pattern matches strings like "guests.123"
preg_match('/^guests\.([^.]+)$/', $property, $matches)

and the $value will be an array like

$value = [
	"ticketType" => 16
]

Please or to participate in this conversation.