Skip to content

Cannot read property 'forEach' of null (NestedTreeControl) #14545

Closed
@stefanobranco

Description

@stefanobranco

What is the expected behavior?

No exceptions will be thrown if there the children of a node are null.

What is the current behavior?

In a nested tree, if the children of a node are null, a 'Cannot read property 'forEach' of null' exception will be thrown:

app.module.ts:59 TypeError: Cannot read property 'forEach' of null
at SafeSubscriber._next (tree.es5.js:339)
at SafeSubscriber../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)
at SafeSubscriber../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134)
at Subscriber../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)
at Subscriber../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at TakeSubscriber../node_modules/rxjs/_esm5/operators/index.js.TakeSubscriber._next (take.js:40)
at TakeSubscriber../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at Observable._subscribe (scalar.js:5)
at Observable../node_modules/rxjs/_esm5/internal/Observable.js.Observable._trySubscribe (Observable.js:43)
at Observable../node_modules/rxjs/_esm5/internal/Observable.js.Observable.subscribe (Observable.js:29)

What are the steps to reproduce?

Create a nested tree where some elements do not have children.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

Typescript: 3.1.6
Angular: 7.0.1
Angular Material: 7.1.0
Chrome 70
Windows 10

Is there anything else we should know?

As far as I can tell, the behaviour changed with #10886. The change to getDescendants removed both the check for null as well as the check for the length of the children. There is a comment pointing to the fact that the check for length is not needed in concert with forEach, which makes sense. However, in my opinion, only the check for length can be safely removed, as otherwise forEach will crash if children is null.

/** A helper function to get descendants recursively. */
  protected _getDescendants(descendants: T[], dataNode: T): void {
    descendants.push(dataNode);
    const childrenNodes = this.getChildren(dataNode);
    if (Array.isArray(childrenNodes)) {
      childrenNodes.forEach((child: T) => this._getDescendants(descendants, child));
    } else if (childrenNodes instanceof Observable) {
      childrenNodes.pipe(take(1)).subscribe(children => {
        /** In my opinion a check is needed here whether children is null */ 
        children.forEach((child: T) => this._getDescendants(descendants, child));
      });
    }
  }

Metadata

Metadata

Assignees

Labels

P3An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions