@ContentChildren is not being populated

You need to use forwardRef to reference classes which are not yet defined. See this plunk. Remember ES6 classes are not hoisted.

@Component({
    selector: 'parent',
    template: '<div><h1>Parent</h1><ng-content></ng-content></div>'
})
export class Parent {
    @ContentChildren(forwardRef(() => Child)) children; // <!- HERE

    ngAfterContentInit() {
        console.log(this.children);
        console.log(this.children.length);
    }
}

UPD Mark Rajcok pointed out an excellent article about forward references in angular2 (see the comment bellow). Must read: thoughtram.io Forward references in Angular 2.


You need to add { descendants: true } to include nested children,

@Component({
    selector: 'parent',
    template: '<div><h1>Parent</h1><ng-content></ng-content></div>'
})
export class Parent {
    @ContentChildren(Child, { descendants: true }) children: QueryList<Child>;
    ngAfterContentInit() {
        console.log(this.children);
        console.log(this.children.length);
    }
}

descendants - True to include all descendants, otherwise include only direct children.


This also happens if your child component references your parent component in the constructor; Angular doesn't like the circular reference!

I needed to choose only one method for parent->child communication: either use ContentChildren OR use the parent component in the child's constructor.

@Component()
export class Parent {
  @ContentChildren(Child)
  private children: QueryList<Child>;
}

@Component()
export class Child {
  constructor(
    // !! Remove the following line to make the ContentChildren "work" again.
    @Optional() parent: Parent
  ) { }
}

Tags:

Angular