F
Filamentā€¢14mo ago
ChesterS

Pass arguments to `DeleteAction` in Livewire component

Is it possible to add a DeleteAction to a component instead of a simple Action and pass arguments to it without overriding the action method? (https://filamentphp.com/docs/3.x/actions/adding-an-action-to-a-livewire-component#passing-action-arguments) Here is some sample code (that doesn't work)
@foreach($this->messages as $message)
{{ $this->deleteMessage($message->id) }} <-- I want something like this
@endforeach
@foreach($this->messages as $message)
{{ $this->deleteMessage($message->id) }} <-- I want something like this
@endforeach
// MyComponent.php
public function deleteMessage(): Action
{
return DeleteAction::make('deleteMessage'); // This won't work as it needs a record
}
// MyComponent.php
public function deleteMessage(): Action
{
return DeleteAction::make('deleteMessage'); // This won't work as it needs a record
}
I can do something like
->action(fn(array $arguments) => Message::find($arguments['message_id'])?->delete()))
->action(fn(array $arguments) => Message::find($arguments['message_id'])?->delete()))
But that kind of defeats the purpose of using a DeleteAction in the 1st place. I tried a couple of things like
{{ ($this->deleteMessage)->record($message) }}
or
{{ ($this->deleteMessage($message->id) }}
...
//
public function deleteMessage($message_id): Action
{
$message = Message::find($message_id);
return DeleteAction::make('deleteMessage')
->record($message);
}
{{ ($this->deleteMessage)->record($message) }}
or
{{ ($this->deleteMessage($message->id) }}
...
//
public function deleteMessage($message_id): Action
{
$message = Message::find($message_id);
return DeleteAction::make('deleteMessage')
->record($message);
}
but nothing seems to work. Any tips/ideas? Am I missing something?
12 Replies
ChesterS
ChesterSOPā€¢14mo ago
My last attempt is this abomination
public function deleteMessage(string $messageId): Action {
$message = Message::findOrFail($messageId);
return DeleteAction::make('deleteMessage')
->requiresConfirmation()
->authorize('delete', $message)
->record($message)
->action(function(array $arguments) {
Message::find($arguments['message_id'])?->delete();
})
;

// Template
{{ ($this->deleteMessage($message->id))(['message_id' => $message->id])}} // Yeah...
public function deleteMessage(string $messageId): Action {
$message = Message::findOrFail($messageId);
return DeleteAction::make('deleteMessage')
->requiresConfirmation()
->authorize('delete', $message)
->record($message)
->action(function(array $arguments) {
Message::find($arguments['message_id'])?->delete();
})
;

// Template
{{ ($this->deleteMessage($message->id))(['message_id' => $message->id])}} // Yeah...
But this also doesn't work. I get Too few arguments to function App\Livewire\MyComponent::deleteMessage(), 0 passed This doesn't work either unfortunately
public function deleteMessage(): Action
{
return DeleteAction::make('deleteMessage')
->record(function (array $arguments) {
return Message::find($arguments['message_id']);
});
}
public function deleteMessage(): Action
{
return DeleteAction::make('deleteMessage')
->record(function (array $arguments) {
return Message::find($arguments['message_id']);
});
}
Lionking-Dev
Lionking-Devā€¢14mo ago
hello @ChesterS It seems like you are trying to add a DeleteAction to a component in Filament and pass arguments to it without overriding the action method. right?
ChesterS
ChesterSOPā€¢14mo ago
Yes
Lionking-Dev
Lionking-Devā€¢14mo ago
Based on the code you provided, it appears that you're trying to call the deleteMessage() method and pass the $message->id as an argument within a loop.
ChesterS
ChesterSOPā€¢14mo ago
Sorry that was just an example to demonstrate what I'm trying to achieve. here is a more sane code
@foreach($messages as $message)
{{ ($this->deleteMessage)(['message_id' => $message->id]) }}
@endforeach
@foreach($messages as $message)
{{ ($this->deleteMessage)(['message_id' => $message->id]) }}
@endforeach
Lionking-Dev
Lionking-Devā€¢14mo ago
Unfortunately, this approach won't work as you cannot directly pass arguments to a DeleteAction without overring the action method. yeah One possible slution is to modify your code as folows php // MyComponent.php public function deleteMessage($messageId): Action { $message = Message::find($messageId); return DeleteAction::make('deleteMessage') ->record($message); } html <!-- Template --> @foreach($this->messages as $message) <button wire:click="deleteMessage({{ $message->id }})">Delete</button> @endforeach I hope this helps!
ChesterS
ChesterSOPā€¢14mo ago
Hmm this doesn't seem to work šŸ¤” Also you lose a lot of the features of using an action (styling, notifications, animations etc) since you create your own button.
Lionking-Dev
Lionking-Devā€¢14mo ago
just second public $selectedMessageId; Define a public property in your component to store the selected message ID and public function deleteMessage($messageId): Action { $this->selectedMessageId = $messageId; return DeleteAction::make('deleteMessage') ->confirm('Are you sure you want to delete this message?') ->onSuccess(function () { // Perform deletion logic here $message = Message::find($this->selectedMessageId); $message->delete(); // Show success notification or perform any other actions $this->alert('success', 'Message deleted successfully!'); }); } šŸ˜€
ChesterS
ChesterSOPā€¢14mo ago
Hey thanks for the message. Yeah this might work but it negates the point of using actions. Not only does it require extra properties for each Component I might need it, but it is also a hacky approach where I duplicate the delete logic on the onSuccess call. All I really need is access to the $arguments variable in the record() method since that is my real problem - I can't set a record on the Action
awcodes
awcodesā€¢14mo ago
{{ ($this->deleteMessage)(['id' => $message->id]) }}
{{ ($this->deleteMessage)(['id' => $message->id]) }}
->onSuccess(function ($arguments) {
// $arguments['id']
})
->onSuccess(function ($arguments) {
// $arguments['id']
})
Also, 'DeleteMessage' method needs to be called 'DeleteMessageAction'
ChesterS
ChesterSOPā€¢14mo ago
@awcodes How would I set the record on the DeleteAction ? eg
public function deleteMessageAction(): Action
{
return DeleteAction::make('deleteMessage')
->requiresConfirmation();
}
public function deleteMessageAction(): Action
{
return DeleteAction::make('deleteMessage')
->requiresConfirmation();
}
gives me the following error Filament\Actions\DeleteAction::Filament\Actions\{closure}(): Argument #1 ($record) must be of type Illuminate\Database\Eloquent\Model, null given, called in /var/www/endor/vendor/filament/support/src/Concerns/EvaluatesClosures.php on line 35 I tried setting the record using
->record(function (array $arguments) {
return Message::find($arguments['message_id']);
});
->record(function (array $arguments) {
return Message::find($arguments['message_id']);
});
but it doesn't work as $arguments is empty
awcodes
awcodesā€¢14mo ago
look at the DeleteAction to see how they are doing it under the hood This is also what it's better to use custom Actions than trying to override one of the prebuild actions.
Want results from more Discord servers?
Add your server