Scenario: A customer can refer a client to another customer. Each referral needs to be stored in a DB table row. The customer receiving the referral should see a notification for the event.
Create a new referral and dispatch the event:
$totalRefers = [];
foreach ($array as $to) {
$refer = new ClientReferral;
$refer->user_id = $user_id;
$refer->by = $by;
$refer->to = $to;
$refer->save();
array_push($totalRefers, $refer);
ReferralSent::dispatch($refer); // Here is the Event
}
return response()->json([
'status' => 'Success',
'message' => 'Client referred successfully to selected professionals.',
'data' => $totalRefers
], 200);
The event broadcastOn()
method:
public function broadcastOn() {
return new PrivateChannel('referral.' . $this->referral->id);
}
The channel:
Broadcast::channel('referral.{id}', function ($user, $id) {
// let's say it's true for the time being
return true;
});
And the request is an Ajax POST so in the success callback:
console.log('referral created');
res.data.forEach(function(entry) {
// window.custom.userId is the authenticated user ID:
if (entry.refer_to == window.custom.userId) {
window.Echo.private('referral.' + entry.id).listen('ReferralSent', ({data}) => {
console.log('You have received a new referral');
});
}
});
Now the issue with the current code is that the receiver cannot subscribe to this channel because the event is created dynamically, and I cannot make the channel name static because the referral came in at run time.
How can a receiver subscribe and listen to dynamic events?
With this logic, I want to get that specific referral and its data to show it in the notification tray in HTML.
How can I achieve this?
The event shown in the question broadcasts to a channel for that specific referral entity only. However, the receiver that subscribes to this channel should receive events for all referral entities referred to them.
Instead of creating the channel context for the referral entity itself, publish to a channel designated for the user that receives the referral. I'm guessing that $referral->to
contains that user's ID:
public function broadcastOn()
{
return new PrivateChannel('referral.' . $this->referral->to);
}
Update the channel to authorize the current user based on the ID of the user that receives the referral:
Broadcast::channel('referral.{refereeId}', function ($user, $refereeId) {
return $user->id == $refereeId;
});
And, on the client-side, listen on the same channel:
window.Echo.private('referral.' + window.custom.userId)
.listen(e => console.log(e.referral));
Because we're not listening for a specific referral ID anymore, we can initialize the Echo subscriber during the page load instead of in the AJAX response callback.
Broadcast events are designed to be useful for real-time actions outside the normal request/response cycle (including AJAX requests). In the case of this question, we want to start Echo listeners for every customer when the page loads—not after a specific request—so that they can receive notifications any time another customer refers a client to them.
The flow looks like this: