F
Filament9mo ago
sidrit

Listening for broadcast events

Hi folks Been working with filament for a little bit now and really enjoying it. I’ve been building with Laravel since v4 now and really liking the productivity bump. Anyhow there’s something I’m trying to wrap my head around on how to do “the filament way”. Let’s assume I have a component (TextEntry, TextColumn etc). For that specific item I know while displaying it, I will be receiving a broadcast notification (say for example a list of processes running in the background and when the state of any changes, I fire an event) Now this would be no mystery with just Laravel using Broastasting + echo. Even in Livewire (which I’ve been using for a long time) it would not be an issue (setting up listeners to subscribe to Echo) How would I got about doing this with one of the filament pages? (Say View or List page) Would it be a custom page treated like a regular Livewire component? Is maybe a custom Field or custom Entry? Receiving these live updates (considering we have everything in the ecosystem even with Reverb coming out) seems like a common scenario but I can’t find a proper information on it Thanks in advance to anyone that could help shed some light
29 Replies
awcodes
awcodes9mo ago
Pages are livewire components if that helps. They can also do polling. So listen however you need to then you should be able to update the form or whatever as needed.
sidrit
sidritOP9mo ago
Thank you @awcodes I got broadcasting (with Reverb) set up. echo.js is in place and i can subscrive to the user's private channel. I can receive events as well. I set up the broadcaster in the filament config and i can already see it is subscribes automatically to the authed user's channel (provided it exists in channels.php). This is all fine and dandy.
awcodes
awcodes9mo ago
Glad you got it working. Kinda of the beauty of filament. It’s still all just laravel and livewire.
sidrit
sidritOP9mo ago
I am looking at this https://livewire.laravel.com/docs/events#real-time-events-using-laravel-echo and i've set up the listeners in the filament page (ViewSite in this case)
protected function getListeners(): array
{
return [
"echo:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted',
];
}

public function handleGlobalCheckCompleted($event): void
{
logger('GlobalCheckCompleted', $event);
}
protected function getListeners(): array
{
return [
"echo:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted',
];
}

public function handleGlobalCheckCompleted($event): void
{
logger('GlobalCheckCompleted', $event);
}
Laravel
Events | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
sidrit
sidritOP9mo ago
The problem is i'm not getting anything on the filament side 😩 and i know that getListeners method is getting called
awcodes
awcodes9mo ago
What do you mean by not getting anything on the filament side. The page is still a livewire component.
sidrit
sidritOP9mo ago
technically speaking i don't even need echo.js (the project is all Filament) so setting up the listeners should be all that is needed (echo.js was set up just as a sanity check).
awcodes
awcodes9mo ago
Sounds like you might be listening for the event on the wrong thing. But I could be wrong.
sidrit
sidritOP9mo ago
The event is fired. I can see it in the queue. I can see it in the reverb debug window and i can even listen for it (outsite of filament in a plain blade file) by subscribing via javascript. The Livewire listener is set up (via getListeners) but the handler (method called handleGlobalCheckCompleted is not invoked).
awcodes
awcodes9mo ago
In Filament panels, the page is the livewire component
sidrit
sidritOP9mo ago
That's clear and fine. I've got the listener set up in a ViewRecord type page, in this case View site. I know that Livewire getListeners is getting called. I can dd in it.
awcodes
awcodes9mo ago
Ok, so what is the actual issue? The listener is getting “heard”, so what is the actual expectation. The listener is firing but what isn’t happening based on it firing?
sidrit
sidritOP9mo ago
The getListeners() method of the component is getting called. But the handler for the given event is not.
protected function getListeners(): array
{
return [
"echo:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted',
];
}
protected function getListeners(): array
{
return [
"echo:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted',
];
}
So i know that GlobalCheckCompletedEvent is getting fired in the system but although the listener is registered, the handler handleGlobalCheckCompleted is never getting called. So either my syntax is wrong, i'm missing something, or GlobalCheckCompletedEvent is not making it in this component. That's the point. The listener is not firing.
awcodes
awcodes9mo ago
It might be too late in the lifecycle. Or too early
sidrit
sidritOP9mo ago
Huh.
awcodes
awcodes9mo ago
Can you verify there is an authenticated user at the point the listener happens.? Granted this might be outside the scope of filament. And more to do with the lifecycle of laravel. Just what is coming to mind presently without a full understanding of the app.
sidrit
sidritOP9mo ago
Yep. when getListeners() is called there is an authed user. The user's id (uuid in this case) is getting pulled correctly. That's the right name for the channel
No description
sidrit
sidritOP9mo ago
I think more than laravel it might be livewire. https://livewire.laravel.com/docs/events#real-time-events-using-laravel-echo. I've used echo and Livewire a number of times before and this has been the m.o. since it appeared as a feature in 2.x
Laravel
Events | Laravel
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.
sidrit
sidritOP9mo ago
Holy shit i got it
awcodes
awcodes9mo ago
Entirely possible
sidrit
sidritOP9mo ago
I should stop doing these things at 3am
awcodes
awcodes9mo ago
lol. 10 pm here. But yes.
sidrit
sidritOP9mo ago
The syntax is a bit different. For private channels it's "echo-private:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted' instead of "echo:App.Models.User." . auth()->id() . ",GlobalCheckCompletedEvent" => 'handleGlobalCheckCompleted' Tomorrow i'm going to figure out how to actually get the listening done on a TextEntry or TextColumn level. This listener here was just to check the piping. But it guess since those are Livewire components as well i'm either going to have to somehow set the listener (i think here is a setListeners() method) when i set up the TextEntry/TextColumn on the injected $livewire or go ahead and define a custom TextEntry/TextColumn and add listening capabilities to those
awcodes
awcodes9mo ago
Should the brodcast handle authorization or a middleware?
sidrit
sidritOP9mo ago
Not sure i understand the question. This broadcast message i was using (and likely the one i will be setting up) will carry over a DTO or just a POPO. It will be on a private channel non the less and likely will need to go through policies
awcodes
awcodes9mo ago
Sorry, I’m probably just not seeing the full picture right right now.
sidrit
sidritOP9mo ago
Here's the idea. Let's imagine an uptime checker or something. You have a list of sites. Either in a table or Infolist. For each one of thse let's stay you have a status item. There is a schedule in the system that periodically fires checks for uptime. When you're looking at the sites list, after the check is done, we update the status with some information. The idea is to get each one of these sites to subscribe to their own channel and listen to their own events. So what i'm trying to do now, before i take the custom TextColumn route is figure out a way to access the $livewire instance for a TextColum while in the table() method. Livewire has a setListeners() method that can be called, well, to register listeners. Yea i think i imagined the setListeners() method. These will have to be custom components 🙂 But no way i'm deaing with this tonight. Have a good rest of the evening man and thatnk you for your help
awcodes
awcodes9mo ago
Fair. For what it’s worth in my mind a poll makes more sense than a broadcast. Instead of keeping a connection open. Just let the browser make a native request for changes and handle it if it’s a dif. But it is relative and something to consider for the use case of the feature.
sidrit
sidritOP9mo ago
It’s a good point. The WS integration on my end is still on the exploratory phase. There will be some things that need an open WS channel no matter what, some that are fine with -some level- of polling and some other ones with a hybrid approach : subscription on a page level and rehydrate only when needed
Want results from more Discord servers?
Add your server