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

pdigital's avatar

FilamentPHP: Livewire Entangle Error: Livewire property cannot be found on component:

New to Livewire and Filament. I'm building an application where I have a public page with a Filament Action. Clicking this actions opens up a model with a wizard step form in it.

I want the questions in the second step to be loaded, dependent on the results of the input in step 1. In step 1. the user fills in a name and Laravel searches the model with that name. If the model is found, it needs to set the model and load the hasMany relationship and use this relationship to dynamically load the questions in step 2. This is what I currently have:

class Home extends Component implements HasForms, HasActions
{
    use InteractsWithActions;
    use InteractsWithForms;

    public ?Attendee $attendee = null;
    public array|Collection $childAttendees = [];

    public function rsvpAction(): Action
    {
        return Action::make('rsvp')
            ->label('RSVP')
            ->slideOver()
            ->steps([
                Step::make('Name')
                    ->description('What is your name?')
                    ->schema([
                        TextInput::make('name')
                            ->required()
                            ->afterStateUpdated(function (Set $set, $state) {
                                $this->attendee = Attendee::where('name', $state)->first();
                                $set('attendee', $this->attendee);
                                if ($this->attendee) {
                                    if ($this->attendee->isMain()) {
                                        $this->childAttendees = $this->attendee->childAttendees;
                                    } else {
                                        $this->childAttendees = $this->attendee->mainAttendee->childAttendees;
                                    }
                                }

                                $set('childAttendees', $this->childAttendees);
                            })
                    ])
                    ->afterValidation(function (Get $get) {
                        if (!$get('attendee') || !$get('childAttendees')) {
                            throw new Halt();
                        }
                    }),
                Step::make('Attendance')
                    ->description('Will you be attending?')
                    ->schema(function (Get $get) {
                        $schema = [];
                        $attendee = $get('attendee');
                        $childAttendees = $get('childAttendees');

                        if (!$attendee || !$childAttendees) {
                            return [];
                        }

                        $schema[] = Toggle::make('willAttend')
                            ->label('Will you attend?');

                        $childAttendeesSchema = $childAttendees->map(function ($childAttendee) {
                            return Toggle::make("childAttendees.{$childAttendee->id}.rsvp")
                                ->label("Will {$childAttendee->name} also attend?");
                        })->toArray();

                        return array_merge($schema, $childAttendeesSchema);
                    }),
            ])
            ->action(function (array $data) {
                info(print_r($data, true));
            });
    }
}

This does load the questions in step 2 as expected, but the Toggles do not work, except the first one ("willAttend"). I see this error:

Livewire Entangle Error: Livewire property ['mountedActionsData.0.willAttend'] cannot be found on component ['home']

And also these errors for each toggle from each HasMany relation:

Alpine Expression Error: Cannot read properties of null (reading '441')

Expression: "{
            state: $wire.$entangle('mountedActionsData.0.childAttendees.441.rsvp', false),
        }"

Any pointers? I think I need to figure out some way for the second step to load only if the Attendee in the first step is found.

I also need to show the user some kind of message when the attendee is not found. Any pointers?

0 likes
4 replies
LaryAI's avatar
Level 58

It seems like you're encountering an issue with Livewire's entanglement with Alpine.js, which is causing the error messages you're seeing. The mountedActionsData property is likely not being properly updated or recognized by Livewire, which is why you're getting the "cannot be found on component" error.

Here's a potential solution to address the issues you're facing:

  1. Ensure that the childAttendees property is properly initialized as a collection. Since you're using it as an array or collection, it's best to initialize it as a collection in the constructor of your Livewire component.

  2. Use Livewire's wire:model or wire:click directives to handle the toggles instead of using $entangle. This will simplify the state management and avoid the entanglement issues.

  3. To show a message when the attendee is not found, you can use a Livewire property to track whether the attendee has been found and display a message conditionally in your Blade template.

Here's how you might adjust your code:

class Home extends Component implements HasForms, HasActions
{
    use InteractsWithActions;
    use InteractsWithForms;

    public ?Attendee $attendee = null;
    public Collection $childAttendees;
    public bool $attendeeNotFound = false;

    public function mount()
    {
        $this->childAttendees = collect();
    }

    public function rsvpAction(): Action
    {
        // ... other code ...

        Step::make('Name')
            // ... other code ...
            ->afterStateUpdated(function (Set $set, $state) {
                $this->attendee = Attendee::where('name', $state)->first();
                if ($this->attendee) {
                    $this->attendeeNotFound = false;
                    $this->childAttendees = $this->attendee->isMain()
                        ? $this->attendee->childAttendees
                        : $this->attendee->mainAttendee->childAttendees;
                } else {
                    $this->attendeeNotFound = true;
                    $this->childAttendees = collect();
                }
            })
            // ... other code ...

        Step::make('Attendance')
            // ... other code ...
            ->schema(function (Get $get) {
                $schema = [];
                $attendee = $get('attendee');
                $childAttendees = $get('childAttendees');

                if (!$attendee || $childAttendees->isEmpty()) {
                    return [];
                }

                $schema[] = Toggle::make('willAttend')
                    ->label('Will you attend?')
                    ->reactive();

                foreach ($childAttendees as $childAttendee) {
                    $schema[] = Toggle::make("childAttendees.{$childAttendee->id}.rsvp")
                        ->label("Will {$childAttendee->name} also attend?")
                        ->reactive();
                }

                return $schema;
            })
            // ... other code ...
    }

    // ... other code ...
}

In your Blade template, you can conditionally show a message if the attendee is not found:

@if($this->attendeeNotFound)
    <div class="alert alert-warning">
        Attendee not found. Please check the name and try again.
    </div>
@endif

Remember to replace the ->reactive() method with the appropriate Livewire directives if needed, such as wire:model or wire:click, depending on how you want to handle the state of your toggles.

This solution should help you manage the state of your component more effectively and display messages to the user when necessary.

pdigital's avatar

@LaryAI This does not work. It still shows the same errors. I also use this in my Blade template:

        {{ $this->rsvpAction }}

To load the form.

pdigital's avatar

I decided to switch over to a Select input. But I still get this error:

Uncaught TypeError: Cannot read properties of null (reading '441')
pdigital's avatar
pdigital
OP
Best Answer
Level 1

Apparently, there was a problem with my array mapping. I swapped out this:

$childAttendeesSchema = $childAttendees->map(function ($childAttendee) {
    return Select::make("childAttendees.{$childAttendee->id}.rsvp")
        ->label("Will {$childAttendee->name} also attend?")
        ->options(['yes' => 'Yes', 'no' => 'No'])
        ->required();
})->toArray();

return array_merge($schema, $childAttendeesSchema);

With a simple foreach loop:

foreach ($childAttendees as $childAttendee) {
    $schema[] = Select::make("childAttendees.{$childAttendee->id}.rsvp")
        ->label("Will {$childAttendee->name} also attend?")
        ->options(['yes' => 'Yes', 'no' => 'No'])
        ->required();
}

return $schema;

Please or to participate in this conversation.