-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
Yes
Description
We have migrated our code base to use the new takeUntilDestroyed pipe along with DestroyRef.
Unfortunately, we have noticed very erratic behavior that with these, going so far as to not actually unsubscribe from some Observables at all after components are destroyed (I am still working on trying to provide a minimal reproduction for some cases).
I have been able to replicate some bugs consistently with the reproduction below.
https://stackblitz.com/edit/at-ng-14-router-aoffwi?file=src%2Fapp%2Fhello.component.ts
Reproduction
This small App contains
A Service with a BehaviorSubject (bhSubject) that increments an integer and a Subject (subject) that "increments" strings.
Those two actions are performed from AppComponent, which is always visible with the buttons.
A third button "Toggle Child" will show and hide the HelloComponent, which contains the actual bug.
HelloComponent registers a onDestroy callback in each of the following cases:
- In the callback given to subscribe() on bhSubject.
- In a method called from the same callback given to subscribe on bhSubject.
- In the callback given to subscribe() on subject.
- In a setTimeout of 0.
- In ngZone.runOutsideAngular()
- Directly in ngOnit()
Note that a lot of the stuff is going on in the console.
Case 1:
- Toggle Child
- Toggle Child again
Expected onDestroy callbacks to have been called:
- 1, 2, 4, 5?, 6
Actual callbacks called
- 2, 4, 6
Case 2:
- Toggle Child
- Int++
- Toggle Child
Expected onDestroy callbacks to have been called:
- 1, 1, 2, 2, 4, 5?, 6
Actual callbacks called
- 1, 2, 2, 4, 6
Case 3:
- Toggle Child
- Letter++
- Toggle Child
Expected onDestroy callbacks to have been called:
- 1, 2, 3, 4, 5?, 6
Actual callbacks called
- 2, 3, 4, 6
Following this, it seems like the first callback from a BehaviorSubject doesn't allow to use DestroyRef.
Now you might be wondering why I added runOutsideAngular() in this, it's normal it's not working there. Well, if we comment the subscription to the normal subject (line 40 to 50 in hello.component.ts) and do case 1 again, it somehow does work with runOutsideAngular(). https://stackblitz.com/edit/at-ng-14-router-d9iur8?file=src%2Fapp%2Fhello.component.ts
/*this.someService.subject
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((value) => {
console.log(value);
this.destroyRef.onDestroy(() => {
console.log('Subject ' + value + ' destroyRef');
});
this.letterValue = value;
});*/Case 4 (Same as Case 1, but with a subscription that is commented out):
- Toggle Child
- Toggle Child again
Expected onDestroy callbacks to have been called:
- 1, 2, 4, 5?, 6
Actual callbacks called
- 2, 4, 5, 6
This all seems very inconsistent. As stated before, we ran into bugs where takeUntilDestroyed() didn't work at all when used on observables within ngOnit directly (with destroyRef supplied, of course) and it wouldn't unsubscribe from all observables. Sadly I've not been able to reproduce this in a simple example yet, but this makes this new feature quite unusable. I'll keep you updated if I manage to craft a minimal reproduction for that bug as well.
Please provide a link to a minimal reproduction of the bug
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
Angular CLI: 16.0.0
Node: 16.18.0
Package Manager: npm 9.6.4
OS: win32 x64
Angular: 16.0.0
... animations, cdk, cli, common, compiler, compiler-cli, core
... forms, localize, material, platform-browser
... platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1600.0
@angular-devkit/build-angular 16.0.0
@angular-devkit/core 16.0.0
@angular-devkit/schematics 16.0.0
@schematics/angular 16.0.0
rxjs 7.8.1
typescript 5.0.4
Anything else?
No response