Skip to content

Commit c08fc3e

Browse files
author
Vivian Hu
committed
Fix(tree):allow NestedTreeControl to have null or undefined child
1 parent 12bf619 commit c08fc3e

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

src/cdk/tree/control/base-tree-control.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export abstract class BaseTreeControl<T> implements TreeControl<T> {
3434
isExpandable: (dataNode: T) => boolean;
3535

3636
/** Gets a stream that emits whenever the given data node's children change. */
37-
getChildren: (dataNode: T) => (Observable<T[]> | T[]);
37+
getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null);
3838

3939
/** Toggles one single data node's expanded/collapsed state. */
4040
toggle(dataNode: T): void {

src/cdk/tree/control/nested-tree-control.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {BaseTreeControl} from './base-tree-control';
1313
export class NestedTreeControl<T> extends BaseTreeControl<T> {
1414

1515
/** Construct with nested tree function getChildren. */
16-
constructor(public getChildren: (dataNode: T) => (Observable<T[]> | T[])) {
16+
constructor(public getChildren: (dataNode: T) => (Observable<T[]> | T[] | undefined | null)) {
1717
super();
1818
}
1919

src/cdk/tree/control/tree-control.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,5 +60,5 @@ export interface TreeControl<T> {
6060
readonly isExpandable: (dataNode: T) => boolean;
6161

6262
/** Gets a stream that emits whenever the given data node's children change. */
63-
readonly getChildren: (dataNode: T) => Observable<T[]> | T[];
63+
readonly getChildren: (dataNode: T) => Observable<T[]> | T[] | undefined | null;
6464
}

src/lib/tree/tree.spec.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,26 @@ describe('MatTree', () => {
237237
});
238238
});
239239

240+
describe('nested tree with undefined or null children', () => {
241+
describe('should initialize', () => {
242+
let fixture: ComponentFixture<MatNestedTreeWithNullOrUndefinedChild >;
243+
244+
beforeEach(() => {
245+
configureMatTreeTestingModule([MatNestedTreeWithNullOrUndefinedChild]);
246+
fixture = TestBed.createComponent(MatNestedTreeWithNullOrUndefinedChild);
247+
treeElement = fixture.nativeElement.querySelector('mat-tree');
248+
249+
fixture.detectChanges();
250+
});
251+
252+
it('with rendered dataNodes', () => {
253+
const nodes = getNodes(treeElement);
254+
255+
expect(nodes).toBeDefined('Expect nodes to be defined');
256+
expect(nodes[0].classList).toContain('customNodeClass');
257+
});
258+
});
259+
});
240260
describe('nested tree', () => {
241261
describe('should initialize', () => {
242262
let fixture: ComponentFixture<NestedMatTreeApp>;
@@ -710,6 +730,29 @@ class MatTreeWithNullOrUndefinedChild {
710730
hasChild = (_: number, node: ExampleFlatNode) => node.expandable;
711731
}
712732

733+
@Component({
734+
template: `
735+
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
736+
<mat-nested-tree-node *matTreeNodeDef="let node" class="customNodeClass">
737+
{{node.name}}
738+
<ng-template matTreeNodeOutlet></ng-template>
739+
</mat-nested-tree-node>
740+
</mat-tree>
741+
`
742+
})
743+
class MatNestedTreeWithNullOrUndefinedChild {
744+
treeControl: NestedTreeControl<FoodNode>;
745+
dataSource: MatTreeNestedDataSource<FoodNode>;
746+
747+
constructor() {
748+
this.treeControl = new NestedTreeControl<FoodNode>(this.getChildren);
749+
this.dataSource = new MatTreeNestedDataSource();
750+
this.dataSource.data = TREE_DATA;
751+
}
752+
753+
private getChildren = (node: FoodNode) => node.children;
754+
}
755+
713756
@Component({
714757
template: `
715758
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">

0 commit comments

Comments
 (0)