Handling dispatch events with named parameters in Filament Action

Hi 👋 I'm trying to dispatch a Wire Element Pro event to open a slide-over from within a reusable Filament action. While this works seamlessly when the action is defined within a Livewire component, it doesn't seem to work as expected in a Filament action. Here’s the code that works well in a Livewire component:
public function joinTeamAction()
{
return Action::make('joinTeam')
->action(fn() => $this->dispatch('slide-over.open', component: 'settings.team.switch-team-slide-over'));
}
public function joinTeamAction()
{
return Action::make('joinTeam')
->action(fn() => $this->dispatch('slide-over.open', component: 'settings.team.switch-team-slide-over'));
}
However, when I try to achieve the same in a Filament action extended class, I encounter issues. Specifically, I believe the dispatch method from the CanDispatchEvent trait differs from Livewire's HandlesEvent logic, causing the following problems:
class JoinTeamAction extends Action
{
protected function setUp()
{
parent::setUp();

$this
->action(function () {
// Unknown named parameter $component
$this->dispatch(
'slide-over.open',
component: 'settings.team.switch-team-slide-over'
);

// The event doesn't trigger the slide-over
$this->dispatch(
'slide-over.open',
['component' => 'settings.team.switch-team-slide-over']
);
});
}
}
class JoinTeamAction extends Action
{
protected function setUp()
{
parent::setUp();

$this
->action(function () {
// Unknown named parameter $component
$this->dispatch(
'slide-over.open',
component: 'settings.team.switch-team-slide-over'
);

// The event doesn't trigger the slide-over
$this->dispatch(
'slide-over.open',
['component' => 'settings.team.switch-team-slide-over']
);
});
}
}
- Named Parameters: The first approach using named parameters (component: 'settings.team.switch-team-slide-over') results in an "Unknown named parameter $component" error. - Array Syntax: The 2nd approach using an associative array doesn't throw an error, but it fails to trigger the slide-over event as intended. I also realise that $this->js() is not usable in this context either. Is there a different method or workaround that would allow me to trigger the slide-over event in this context? 🙏
Solution:
Actions aren’t livewire components so ‘$this’ is the action in this context. You can inject $livewire into the action callback and call $livewire->dispatch() etc.
Jump to solution
7 Replies
Solution
awcodes
awcodes3mo ago
Actions aren’t livewire components so ‘$this’ is the action in this context. You can inject $livewire into the action callback and call $livewire->dispatch() etc.
Grégoire
Grégoire3mo ago
That's a great idea! And thanks for all your work with Filament. Quick question, how would you deal with component injection inside a Livewire component? According to the documentation I just need to pass Component $livewire. I end up with something like:
Filament\Forms\ComponentContainer::make(): Argument #1 ($livewire) must be of type Filament\Forms\Contracts\HasForms, App\Livewire\Header\Dropdown\SwitchTeam given
Am I missing something here?
class JoinTeamAction extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->action(fn(Component $livewire) => $livewire->dispatch('slide-over.open', component: 'settings.team.switch-team-slide-over'));
}
}

// ...

class SwitchTeam extends Component
{
use InteractsWithActions;
use InteractsWithForms;

public function joinTeam(): Action
{
return JoinTeamAction::make();
}
}
class JoinTeamAction extends Action
{
protected function setUp(): void
{
parent::setUp();

$this->action(fn(Component $livewire) => $livewire->dispatch('slide-over.open', component: 'settings.team.switch-team-slide-over'));
}
}

// ...

class SwitchTeam extends Component
{
use InteractsWithActions;
use InteractsWithForms;

public function joinTeam(): Action
{
return JoinTeamAction::make();
}
}
Dennis Koch
Dennis Koch3mo ago
Any reason you use WireElements over Filament Actions here?
Grégoire
Grégoire3mo ago
To be honest, I am slowly moving away from wire elements to filament elements, but I have to work with a bit of both at the moment.
Dennis Koch
Dennis Koch3mo ago
I end up with something like: Filament\Forms\ComponentContainer::make(): Argument #1 ($livewire) must be of type Filament\Forms\Contracts\HasForms, App\Livewire\Header\Dropdown\SwitchTeam given
Where is this coming from? Can you share the stack trace.
Grégoire
Grégoire3mo ago
Yes, of course! The trace is attached. I also took the time to create a minimal repo. Just go to /test to reproduce it. Let me know if I can do anything to assist.
Grégoire
Grégoire3mo ago
Never mind! After changing the file several times, I forgot to put back implements HasActions, HasForms, which caused the problem. Thanks for your time both of you! ❤️
Want results from more Discord servers?
Add your server