8

I am successfully using <ng-content></ng-content> to show a component in a grandchild as answered here: Father-to-son component tree with guest component, but now I would like to use @ContentChild in that grandchild to access the passed in content, but I can't seem to get anything working.

Here is my attempt using a selector and @ContentChild in a stackBlitz: https://stackblitz.com/edit/angular-dpu4pm . No matter what I do, the @ContentChild is always undefined in TheChild component, but works in TheParent component.

@Component({
  selector: 'spinner',
  template: `
    spinner
  `,
})

@Component({
  selector: 'my-app',
  template: `
    works <the-parent><spinner #spin></spinner></the-parent>
  `,
})

@Component({
  selector: 'the-parent',
  template: 'this is parent <the-child><ng-content #content></ng-content></the-child>'
})
export class TheParent  implements AfterViewInit{

   @ContentChild('spin') spin;

  ngAfterViewInit() {
    alert('parents spin is '+typeof this.spin);  //object
  }
}

@Component({
  selector: 'the-child',
  template: 'this is child <ng-content></ng-content>'
})
export class TheChild  implements AfterViewInit{

  @ContentChild('spin') spin;
   @ContentChild('content') content;

  ngAfterViewInit() {
    alert('childs spin is '+typeof this.spin); //undefined
    alert('childs content is '+typeof this.content); //undefined
  }

}

Any advice on how to make this work, or any other approach to access the grandparent from the grandchild would be much appreciated.

Learning2Code
  • 521
  • 9
  • 21
  • 1
    Please, avoid external reference like plunker for your code, add it to your question (you can keep the plunker for reference but the question should be self sufficient in case of beoken link). – n00dl3 Mar 13 '17 at 23:54
  • For content you should use the `ngAfterContentInit()` instead of `ngAfterViewInit()`. It still didn't work in Plunker for me – Günter Zöchbauer Mar 29 '17 at 15:42
  • 1
    I'm sure this used to work. At least with `@ContentChildren('spin',{descendants: true}) spin;` (not sure what the default for `descendants` is for `ContentChild` and `ContentChildren`) – Günter Zöchbauer Mar 29 '17 at 15:48
  • Maybe you can take another approach? If this is really a spinner and you want to interact with it, why don't you simply use a `SpinnerService` for that? – Zlatko Mar 07 '18 at 08:36
  • The spinner is just an example – Learning2Code May 11 '18 at 17:24
  • But in order to use contentchild you must define a template vraiable to identify the element. plus ng-content is not translated in real DOM element. If you change it to lets say span, it will work – Vega Jan 03 '19 at 16:26
  • I'm not sure I follow, changing the child template to `template: 'this is child '` produces the same results. Is that what you meant? – Learning2Code Jan 03 '19 at 16:58
  • Change to . If you check dev-tools you will see ng-content is not added to the DOM, thus #content reference doesn't exist – Vega Jan 03 '19 at 17:13

0 Answers0