Skip to content

Commit 4c4893e

Browse files
Merge pull request #459 from thoresuenert/fix/use-echo-notification-teardown
Add stopListeningForNotification
2 parents 7b3693c + 4157613 commit 4c4893e

File tree

5 files changed

+32
-6
lines changed

5 files changed

+32
-6
lines changed

packages/laravel-echo/src/channel/channel.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ export abstract class Channel {
1010
*/
1111
options: EchoOptionsWithDefaults<BroadcastDriver>;
1212

13+
/**
14+
* The name for Broadcast Notification Created events.
15+
*/
16+
notificationCreatedEvent: string =
17+
".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated";
18+
1319
/**
1420
* Listen for an event on the channel instance.
1521
*/
@@ -26,17 +32,21 @@ export abstract class Channel {
2632
* Listen for an event on the channel instance.
2733
*/
2834
notification(callback: CallableFunction): this {
29-
return this.listen(
30-
".Illuminate\\Notifications\\Events\\BroadcastNotificationCreated",
31-
callback,
32-
);
35+
return this.listen(this.notificationCreatedEvent, callback);
3336
}
3437

3538
/**
3639
* Stop listening to an event on the channel instance.
3740
*/
3841
abstract stopListening(event: string, callback?: CallableFunction): this;
3942

43+
/**
44+
* Stop listening for notification events on the channel instance.
45+
*/
46+
stopListeningForNotification(callback: CallableFunction): this {
47+
return this.stopListening(this.notificationCreatedEvent, callback);
48+
}
49+
4050
/**
4151
* Stop listening for a whisper event on the channel instance.
4252
*/

packages/react/src/hooks/use-echo.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,15 @@ export const useEchoNotification = <
229229
return;
230230
}
231231

232+
result.channel().stopListeningForNotification(cb);
233+
232234
listening.current = false;
233235
}, [cb]);
234236

235237
useEffect(() => {
236238
listen();
239+
240+
return () => stopListening();
237241
}, dependencies.concat(events.current));
238242

239243
return {

packages/react/tests/use-echo.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ vi.mock("laravel-echo", () => {
1111
listen: vi.fn(),
1212
stopListening: vi.fn(),
1313
notification: vi.fn(),
14+
stopListeningForNotification: vi.fn(),
1415
};
1516

1617
const mockPublicChannel = {
@@ -1040,10 +1041,11 @@ describe("useEchoNotification hook", async () => {
10401041
echoModule.useEchoNotification(channelName, mockCallback),
10411042
);
10421043

1043-
expect(echoInstance.private).toHaveBeenCalledWith(channelName);
1044+
const channel = echoInstance.private(channelName);
10441045

10451046
expect(() => unmount()).not.toThrow();
10461047

1048+
expect(channel.stopListeningForNotification).toHaveBeenCalled();
10471049
expect(echoInstance.leaveChannel).toHaveBeenCalledWith(
10481050
`private-${channelName}`,
10491051
);
@@ -1112,8 +1114,11 @@ describe("useEchoNotification hook", async () => {
11121114
expect(channel.notification).toHaveBeenCalledTimes(1);
11131115

11141116
result.current.stopListening();
1117+
expect(channel.stopListeningForNotification).toHaveBeenCalled();
1118+
11151119
result.current.listen();
11161120

1121+
// notification should still only be called once due to initialized check
11171122
expect(channel.notification).toHaveBeenCalledTimes(1);
11181123
});
11191124

packages/vue/src/composables/useEcho.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,18 @@ export const useEchoNotification = <
237237
return;
238238
}
239239

240+
result.channel().stopListeningForNotification(cb);
240241
listening.value = false;
241242
};
242243

243244
onMounted(() => {
244245
listen();
245246
});
246247

248+
onUnmounted(() => {
249+
stopListening();
250+
});
251+
247252
return {
248253
...result,
249254
/**

packages/vue/tests/useEcho.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ vi.mock("laravel-echo", () => {
134134
listen: vi.fn(),
135135
stopListening: vi.fn(),
136136
notification: vi.fn(),
137+
stopListeningForNotification: vi.fn(),
137138
};
138139

139140
const mockPublicChannel = {
@@ -923,10 +924,11 @@ describe("useEchoNotification hook", async () => {
923924
undefined,
924925
);
925926

926-
expect(echoInstance.private).toHaveBeenCalledWith(channelName);
927+
const channel = echoInstance.private(channelName);
927928

928929
wrapper.unmount();
929930

931+
expect(channel.stopListeningForNotification).toHaveBeenCalled();
930932
expect(echoInstance.leaveChannel).toHaveBeenCalledWith(
931933
`private-${channelName}`,
932934
);

0 commit comments

Comments
 (0)