From c029c678d9587d3bbeeb60720b226c83ec52bedf Mon Sep 17 00:00:00 2001 From: skrtheboss Date: Tue, 18 Apr 2023 11:37:04 +0200 Subject: [PATCH] fix(core): ensure takeUntilDestroyed unregisters onDestroy listener on unsubscribe (#49901) The takeUntilDestroyed must always remove the onDestroy listener, in the teardown logic. PR Close #49901 --- .../core/rxjs-interop/src/take_until_destroyed.ts | 3 ++- .../rxjs-interop/test/take_until_destroyed_spec.ts | 13 +++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/core/rxjs-interop/src/take_until_destroyed.ts b/packages/core/rxjs-interop/src/take_until_destroyed.ts index d026d960f253f..c409aee61935e 100644 --- a/packages/core/rxjs-interop/src/take_until_destroyed.ts +++ b/packages/core/rxjs-interop/src/take_until_destroyed.ts @@ -27,7 +27,8 @@ export function takeUntilDestroyed(destroyRef?: DestroyRef): MonoTypeOperator } const destroyed$ = new Observable(observer => { - destroyRef!.onDestroy(observer.next.bind(observer)); + const unregisterFn = destroyRef!.onDestroy(observer.next.bind(observer)); + return unregisterFn; }); return (source: Observable) => { diff --git a/packages/core/rxjs-interop/test/take_until_destroyed_spec.ts b/packages/core/rxjs-interop/test/take_until_destroyed_spec.ts index 6f933ea806e61..6353f275a1001 100644 --- a/packages/core/rxjs-interop/test/take_until_destroyed_spec.ts +++ b/packages/core/rxjs-interop/test/take_until_destroyed_spec.ts @@ -63,4 +63,17 @@ describe('takeUntilDestroyed', () => { source$.next(2); expect(last).toBe(1); }); + + it('should unregister listener if observable is unsubscribed', () => { + const injector = Injector.create({providers: []}) as EnvironmentInjector; + const destroyRef = injector.get(DestroyRef); + const unregisterFn = jasmine.createSpy(); + spyOn(destroyRef, 'onDestroy').and.returnValue(unregisterFn); + + const subscription = new BehaviorSubject(0).pipe(takeUntilDestroyed(destroyRef)).subscribe(); + + subscription.unsubscribe(); + + expect(unregisterFn).toHaveBeenCalled(); + }); });