Is this a regression?
The previous version in which this bug was not present was
No response
Description
https://github.com/angular/components/blob/652dd334ff22568f6e1d02ef2e7741be10cdc867/src/cdk/tree/tree.ts#L1396C3-L1407C4
Missing takeUntil in the CdkTreeNode registers subscriber and leaves it dangling after destruction.
This is not the only place preventing GC to collect TreeNode, other problem is _nodes Map used for BehaviourSubject value mapping Data to TreeNode. This map keeps old values.
I see the takeUntil was added in patch 20.0.5, I don't know whether it's safe to patch it in version 19.
I do not see CdkTreeNode.ngOnDestroy containing unregisterNode and I do not know why is that, while ngOnInit contains registerNode. Don't know whether it's mistake or intention to leave it registered even on destroy.
Reproduction
StackBlitz link (needed modifications in steps to reproduce): https://stackblitz.com/run?file=src%2Fexample%2Ftree-nested-child-accessor-overview-example.ts
Steps to reproduce:
- open up example controller from the provided stackBlitz link
- set dataSource to
new BehaviorSubject<FoodNode[]>([]);
- add the constructor to consecutively change dataSource nodes
constructor(private readonly cdr: ChangeDetectorRef) {
this.rs();
}
private rs(): void {
if (this.i === 5) {
return
}
setTimeout(() => {
this.dataSource.next([{
name: 'Fruite ' + ++this.i,
children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
}, {
name: 'Salame ' + this.i,
children: [{ name: 'Apple' }, { name: 'Banana' }, { name: 'Fruit loops' }],
}])
this.rs();
},300);
}
- Debug detached nodes in chrome
- When fixing this issue alone _nodes value map in Tree has to be also cleaned
// Suggested fix for the point #5 is to:
export class CdkTreeNode...
...ngOnDestroy(): void {
....
this._tree.unregisterNode(this) // to match register node in ngOnInit
...
Expected Behavior
TakeUntil should be implemented to prevent dangling references and enable cleanup by GC.
Actual Behavior
Nodes kept detached unable to be cleaned up by GC.
Environment
- Angular: 19.2.19
- CDK/Material: 19.2.19
- Browser(s): any
- Operating System (e.g. Windows, macOS, Ubuntu): any
Is this a regression?
The previous version in which this bug was not present was
No response
Description
https://github.com/angular/components/blob/652dd334ff22568f6e1d02ef2e7741be10cdc867/src/cdk/tree/tree.ts#L1396C3-L1407C4
Missing takeUntil in the CdkTreeNode registers subscriber and leaves it dangling after destruction.
This is not the only place preventing GC to collect TreeNode, other problem is
_nodesMap used for BehaviourSubject value mapping Data to TreeNode. This map keeps old values.I see the takeUntil was added in patch
20.0.5, I don't know whether it's safe to patch it in version 19.I do not see CdkTreeNode.ngOnDestroy containing unregisterNode and I do not know why is that, while ngOnInit contains registerNode. Don't know whether it's mistake or intention to leave it registered even on destroy.
Reproduction
StackBlitz link (needed modifications in steps to reproduce): https://stackblitz.com/run?file=src%2Fexample%2Ftree-nested-child-accessor-overview-example.ts
Steps to reproduce:
new BehaviorSubject<FoodNode[]>([]);Expected Behavior
TakeUntil should be implemented to prevent dangling references and enable cleanup by GC.
Actual Behavior
Nodes kept detached unable to be cleaned up by GC.
Environment