After Successful Queue'ed Job, Trigger Update on Filament Panel Form Field?

Is there a way I can update a Filament Form Panel's Field after successfully processing a queue'ed job? I currently have the queue working successfully but I have to do a full page refresh after the queue'ed job successfully runs to see the updated 'title' field. I imagine I'd have to emit a Laravel Event and someone have the filament frontened trigger when that event fires?
Portion of Filament Form File Calling the Queue Job:

Name of Partial File: ContentResource.php
Portion of Filament Form File Calling the Queue Job:

Name of Partial File: ContentResource.php
TextInput::make('title'), Actions::make([ Action::make('generateTitlessssdfdsfsdf') ->icon('heroicon-m-sparkles') ->label('Generate Title') ->tooltip('Generate a title for this article.') ->action(function (Content $content, Set $set) { ProcessGeneratedContent::dispatch($content, PromptType::TITLE); }) ])->alignment(Alignment::Right),
```
6 Replies
bogus
bogus6mo ago
>>Is there a way I can update a Filament Form Panel's Field after successfully processing a queue'ed job? yes, stop using Queue'ed Job
Alex Maven
Alex Maven6mo ago
I’ve made that work with small requests as a test but some of these jobs make take 5 plus minutes and would time out on a normal request
bwurtz999
bwurtz9996mo ago
I've never done this so I'm just guessing, but I think you could do this with broadcasting
bwurtz999
bwurtz9996mo ago
Laravel - The PHP Framework For Web Artisans
Laravel is a PHP web application framework with expressive, elegant syntax. We’ve already laid the foundation — freeing you to create without sweating the small things.
bwurtz999
bwurtz9996mo ago
I don't think Filament supports this out of the box, so you would have to do it yourself But if you broadcasted an event when the job was complete and the page was listening for that event, you could trigger a refresh from the JS
Alex Maven
Alex Maven6mo ago
I was thinking this could be accomplished somehow with this Filament ListenToEvents.php file
<?php

namespace Filament\Forms\Components\Concerns;

use Closure;

trait ListensToEvents
{
/**
* @var array<string, array<Closure>>
*/
protected array $listeners = [];

public function dispatchEvent(string $event, mixed ...$parameters): static
{
foreach ($this->getListeners($event) as $callback) {
$callback($this, ...$parameters);
}

return $this;
}

/**
* @param array<string, array<Closure>> $listeners
*/
public function registerListeners(array $listeners): static
{
foreach ($listeners as $event => $callbacks) {
$this->listeners[$event] = [
...$this->getListeners($event),
...$callbacks,
];
}

return $this;
}

/**
* @return array<string | int, array<Closure> | Closure>
*/
public function getListeners(?string $event = null): array
{
$listeners = $this->listeners;

if ($event) {
return $listeners[$event] ?? [];
}

return $listeners;
}
}
<?php

namespace Filament\Forms\Components\Concerns;

use Closure;

trait ListensToEvents
{
/**
* @var array<string, array<Closure>>
*/
protected array $listeners = [];

public function dispatchEvent(string $event, mixed ...$parameters): static
{
foreach ($this->getListeners($event) as $callback) {
$callback($this, ...$parameters);
}

return $this;
}

/**
* @param array<string, array<Closure>> $listeners
*/
public function registerListeners(array $listeners): static
{
foreach ($listeners as $event => $callbacks) {
$this->listeners[$event] = [
...$this->getListeners($event),
...$callbacks,
];
}

return $this;
}

/**
* @return array<string | int, array<Closure> | Closure>
*/
public function getListeners(?string $event = null): array
{
$listeners = $this->listeners;

if ($event) {
return $listeners[$event] ?? [];
}

return $listeners;
}
}
I'll look into the Livewire documentation but I was thinking if I could put a 'listener' on a field and maybe 'dispatch' that livewire event at the end of the queued job that could potentially update it on that field dynamically without a page reload. I'm looking there the filament documentation for anything related to listeners but it pretty sparse and my limited development skills are having trouble putting it together. Thinking out load it looks like maybe I have to 'register' all the listeners somehere in the form, then put a getListeners method on the field itself, and then have the dispatchEvent method or something like it target that listener and fire it at the end of the queue'ed up job Here is what ChatGPT said, I'm just wondering how to incorporate this with Filament's premade panel livewire components and helpers. Dispatch the Job: When you need to perform a background task, you dispatch a job to the queue. Use Database Model Events: Laravel's Eloquent models fire several events, allowing you to hook into various points in the model's lifecycle. You can listen for the updated event on the model that is being changed by your queued job. Broadcasting Events: When the model is updated, you can broadcast an event using Laravel's event broadcasting. This event should carry the necessary data or identifiers that your Livewire component needs to know which record was updated. Listen on the Frontend: In your Livewire component, listen for the broadcast event. Livewire can listen to Laravel Echo events using the $listeners property. Refresh the Component: Once the Livewire component catches the broadcast event, you can refresh the component's data by re-fetching it from the database. Here's a basic example: php Copy code // In your Livewire component protected $listeners = ['ModelUpdated' => 'refreshData']; public function mount() { $this->refreshData(); } public function refreshData() { // Fetch fresh data from the database $this->modelData = YourModel::find($this->modelId); } And in your event broadcasting setup: php Copy code // In your Event class public function broadcastOn() { return new PrivateChannel('channel-name'); } public function broadcastWith() { return ['modelId' => $this->model->id]; } Remember, you'll need to set up Laravel Echo and a broadcasting driver (like Pusher or Laravel Websockets) to use real-time event broadcasting. Also, ensure that your Livewire component is properly set to listen for the specific event you're broadcasting. This approach maintains a real-time feel to the application, where backend changes are reflected almost instantly on the frontend without manual refreshes.