title: Angular 4 - nested @ViewChild is undefined
body: <p>I'm having trouble to get a <code>@ViewChild</code> annotated field properly initialized under following circumstance:</p>
  
  <p>A <code>@ViewChild</code> annotated field stays <code>undefined</code> under certain circumstances:</p>
  
  <ul>
  <li>Parent component of type <code>X</code> implements abstract base class of type <code>XBase</code>, which has three abstract fields</li>
  <li>Component of type <code>X</code> annotates these field with <code>@ChildView</code> of types <code>A</code>, <code>B</code> and <code>C</code></li>
  <li><code>C</code> in turn also extends <code>XBase</code>, but uses a different template and selector than <code>X</code></li>
  <li>Fields of type <code>A</code> and <code>B</code> get propery initialized in component of type <code>X</code></li>
  <li>Field of type <code>C</code> stays undefined</li>
  </ul>
  
  <p><strong>This is the shortened version of my code</strong></p>
  
  <pre><code>@Component({
      moduleId: module.id,
      selector: 'drive-view'
      templateUrl: './../../html/drive-view.html'
  })   
  export class DriveViewComponent extends GridView&lt;Drive&gt;
  {
      @ViewChild(DriveGridComponent)
      public grid: DriveGridComponent;
  
      @ViewChild(DriveDetailsComponent)
      public itemDetails: DriveDetailsComponent;
  
      @ViewChild(DriveFilterModalComponent)
      public filterModal: DriveFilterModalComponent;
  
      @ViewChild(DriveMembersModalComponent)
      public driveMembersModal: DriveMembersModalComponent;
  }
  
  export abstract class GridView&lt;TEntity&gt;
  {
      public abstract grid: Grid&lt;TEntity&gt;;
      public abstract filterModal: IGridFilterModal;
      public abstract itemDetails: IGridItemDetails&lt;TEntity&gt;;
  }
  
  export abstract class Grid&lt;TEntity&gt;
  {
      public abstract header: IGridHeader;
      public abstract body: IGridBody&lt;TEntity&gt;;
  }
  
  @Component({
      moduleId: module.id,
      selector: '[drive-grid]',
      templateUrl: './../../html/grid.html'
  })    
  export class DriveGridComponent extends Grid&lt;Drive&gt;
  {
      @ViewChild(DriveGridHeaderComponent)
      public header: DriveGridHeaderComponent;
  
      @ViewChild(DriveGridBodyComponent)
      public body: DriveGridBodyComponent;
  }
  
  @Component({
      moduleId: module.id,
      selector: 'thead [grid-header]',
      templateUrl: './../../html/drive-grid-header.html'
  })
  export class DriveGridHeaderComponent implements IGridHeader
  {
      // nothing to see here...
  }
  
  @Component({
      moduleId: module.id,
      selector: 'tbody [grid-body]',
      templateUrl: './../../html/drive-grid-body.html'
  })
  export class DriveGridBodyComponent implements IGridBody&lt;Drive&gt;
  {
      // nothing to see here...
  }
  
  @Component({
      moduleId: module.id,
      selector: '[drive-members-modal]',
      templateUrl: './../../html/drive-members-modal.html'
  })
  export class DriveMembersModalComponent extends GridView&lt;User&gt; 
  {
      @ViewChild(UserGridComponent)
      public grid: UserGridComponent;
  }
  
  @Component({
      moduleId: module.id,
      selector: '[user-grid]',
      templateUrl: './../../html/grid.html'
  })
  export class UserGridComponent extends Grid&lt;User&gt;
  { 
      @ViewChild(UserGridHeaderComponent)
      public header: UserGridHeaderComponent;
  
      @ViewChild(UserGridBodyComponent)
      public body: UserGridBodyComponent;
  }
  </code></pre>
  
  <p><code>UserGridHeaderComponent</code> and <code>UserGridBodyComponent</code> are equivalent to the <code>Drive-</code>Components.</p>
  
  <p>And here are the relevant parts of html templates:</p>
  
  <p><strong>drive-view.html</strong></p>
  
  <pre><code>&lt;div class="row"&gt;
      &lt;div class="col-lg-12"
           drive-filter-modal
           (onFilterApplyButtonEmitter)="onFilterApplyButton()"&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row"&gt;
      &lt;div class="col-lg-12"
           drive-members-modal&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row" [hidden]="!grid.body?.items"&gt;
      &lt;div class="col-lg-12"
            drive-grid
            (onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"
            (onDetailsButtonEmitter)="onDetailsButton($event)"&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="row"
       id="row-grid-item-details"&gt;
      &lt;div class="col-lg-12"
           [@detailsSlideUpDown]="itemDetails.fadeInOutStatus"&gt;
          &lt;item-details (onOpenModalEmitter)="onDriveMembersButton()"&gt;&lt;/item-details&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>grid.html</strong></p>
  
  <pre><code>&lt;div class="table-responsive"&gt;
    &lt;table class="grid table table-hover"&gt;
      &lt;thead grid-header (onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"&gt;&lt;/thead&gt;
      &lt;tbody grid-body (onDetailsButtonEmitter)="onDetailsButton($event)"
             [ngClass]="{'fadeIn': body?.items, 'fadeOut': !body?.items}"
             class="animated"&gt;&lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p><strong>drive-members-modal.html</strong></p>
  
  <pre><code>&lt;div class="modal fade" id="drive-members-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"&gt;
      &lt;div class="modal-dialog modal-lg" role="document"&gt;
          &lt;div class="modal-content"&gt;
              &lt;div class="modal-header"&gt;
                  &lt;button type="button" class="close" data-dismiss="modal" aria-label="Close"&gt;
                      &lt;span aria-hidden="true"&gt;&amp;times;&lt;/span&gt;
                  &lt;/button&gt;
                  &lt;h4 class="modal-title"&gt;Members of 'NAME'&lt;/h4&gt;
              &lt;/div&gt;
              &lt;div class="modal-body"&gt;
                  &lt;div class="row"&gt;
                      &lt;div class="col-lg-12"
                           user-grid
                           (onColumnHeaderToggledEmitter)="onColumnHeaderToggled($event)"
                           (onDetailsButtonEmitter)="onDetailsButton($event)"&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;div class="modal-footer"&gt;
                      &lt;button type="button" class="btn btn-default" data-dismiss="modal"&gt;
                          &lt;span class="glyphicon glyphicon-chevron-left"&gt;&lt;/span&gt; Back
                      &lt;/button&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>So what I'm trying to do is to reuse the <code>GridView&lt;T&gt;</code> in shape of the <code>DriveMembersModalComponent</code> within the <code>DriveViewComponent</code>. It is supposed to render a similar grid within the bootstrap modal that pops up, when the user wants to view the members of a drive. </p>
  
  <p>However <code>DriveViewComponent</code>'s <code>driveMembersModal</code> does not get fully initialized. Its</p>
  
  <pre><code>@ViewChild(UserGridComponent)
  public grid: UserGridComponent;
  </code></pre>
  
  <p>stays undefined. It seems like angular can't find a matching element in the template. I've tried with different selectors with no effect. I've also tried the <code>@ViewChild(&lt;reference&gt;)</code> syntax, where a <code>#reference</code> attribute is added to the element. However this gives me a <code>ElementRef</code>, which I don't know how to handle. It appears to be just a DOM-reference, but not an angular component.</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>I've created a plunker example from my app: <a href="https://embed.plnkr.co/083a5AnkaiCG796adTkR/" rel="nofollow noreferrer">https://embed.plnkr.co/083a5AnkaiCG796adTkR/</a></p>
  
  <p>Follow these instructions to reproduce the error:</p>
  
  <ul>
  <li>Open up your browser's debug mode to see the console output</li>
  <li>Click on the "Drives" tab</li>
  <li>The console will print the <code>DriveMembersModalComponent</code>, it corresponds to component <code>C</code> mentioned above. The <code>grid</code> field is <code>undefined</code>. The print is executed in the <code>DriveViewComponent</code>'s <code>ngAfterViewInit()</code></li>
  </ul>