{"id":523,"hash":"22cb7e0eed3ede3b9fd9bac12e695f78fe07f1882013e0c7f8bfc392a7669b49","pattern":"Angular 2 @ViewChild annotation returns undefined","full_message":"I am trying to learn Angular 2.\n\nI would like to access to a child component from a parent component using the @ViewChild Annotation.\n\nHere some lines of code:\n\nIn BodyContent.ts I have:\n\nimport { ViewChild, Component, Injectable } from 'angular2/core';\nimport { FilterTiles } from '../Components/FilterTiles/FilterTiles';\n\n@Component({\n    selector: 'ico-body-content',\n    templateUrl: 'App/Pages/Filters/BodyContent/BodyContent.html',\n    directives: [FilterTiles] \n})\nexport class BodyContent {\n    @ViewChild(FilterTiles) ft: FilterTiles;\n\n    public onClickSidebar(clickedElement: string) {\n        console.log(this.ft);\n        var startingFilter = {\n            title: 'cognomi',\n            values: [ 'griffin', 'simpson' ]\n        }\n        this.ft.tiles.push(startingFilter);\n    } \n}\n\nwhile in FilterTiles.ts:\n\n import { Component } from 'angular2/core';\n\n @Component({\n     selector: 'ico-filter-tiles',\n     templateUrl: 'App/Pages/Filters/Components/FilterTiles/FilterTiles.html'\n })\n export class FilterTiles {\n     public tiles = [];\n\n     public constructor(){};\n }\n\nFinally here the templates (as suggested in comments):\n\nBodyContent.html\n\n<div (click)=\"onClickSidebar()\" class=\"row\" style=\"height:200px; background-color:red;\">\n    <ico-filter-tiles></ico-filter-tiles>\n</div>\n\nFilterTiles.html\n\n<h1>Tiles loaded</h1>\n<div *ngFor=\"#tile of tiles\" class=\"col-md-4\">\n     ... stuff ...\n</div>\n\nFilterTiles.html template is correctly loaded into  ico-filter-tiles tag (indeed I am able to see the header).\n\nNote: the BodyContent class is injected inside another template (Body) using DynamicComponetLoader: dcl.loadAsRoot(BodyContent, '#ico-bodyContent', injector):\n\nimport { ViewChild, Component, DynamicComponentLoader, Injector } from 'angular2/core';\nimport { Body } from '../../Layout/Dashboard/Body/Body';\nimport { BodyContent } from './BodyContent/BodyContent';\n\n@Component({\n    selector: 'filters',\n    templateUrl: 'App/Pages/Filters/Filters.html',\n    directives: [Body, Sidebar, Navbar]\n})\nexport class Filters {\n\n    constructor(dcl: DynamicComponentLoader, injector: Injector) {\n       dcl.loadAsRoot(BodyContent, '#ico-bodyContent', injector);\n       dcl.loadAsRoot(SidebarContent, '#ico-sidebarContent', injector);\n   } \n}\n\nThe problem is that when I try to write ft into the console log, I get undefined, and of course I get an exception when I try to push something inside the \"tiles\" array: 'no property tiles for \"undefined\"'.\n\nOne more thing: FilterTiles component seems to be correctly loaded, since I'm able to see the html template for it.\n\nAny suggestions?","ecosystem":"npm","package_name":"typescript","package_version":null,"solution":"I had a similar issue and thought I'd post in case someone else made the same mistake. First, one thing to consider is AfterViewInit; you need to wait for the view to be initialized before you can access your @ViewChild. However, my @ViewChild was still returning null. The problem was my *ngIf. The *ngIf directive was killing my controls component so I couldn't reference it.\n\nimport { Component, ViewChild, OnInit, AfterViewInit } from 'angular2/core';\nimport { ControlsComponent } from './controls/controls.component';\nimport { SlideshowComponent } from './slideshow/slideshow.component';\n\n@Component({\n  selector: 'app',\n  template: `\n    <controls *ngIf=\"controlsOn\"></controls>\n    <slideshow (mousemove)=\"onMouseMove()\"></slideshow>\n  `,\n  directives: [SlideshowComponent, ControlsComponent],\n})\nexport class AppComponent {\n  @ViewChild(ControlsComponent) controls: ControlsComponent;\n\n  controlsOn: boolean = false;\n\n  ngOnInit() {\n    console.log('on init', this.controls);\n    // this returns undefined\n  }\n\n  ngAfterViewInit() {\n    console.log('on after view init', this.controls);\n    // this returns null\n  }\n\n  onMouseMove(event) {\n    this.controls.show();\n    // throws an error because controls is null\n  }\n}\n\nEDIT\n\nAs mentioned by @Ashg below, a solution is to use @ViewChildren instead of @ViewChild.","confidence":0.95,"source":"stackoverflow","source_url":"https://stackoverflow.com/questions/34947154/angular-2-viewchild-annotation-returns-undefined","votes":403,"created_at":"2026-04-19T04:51:17.800801+00:00","updated_at":"2026-04-19T04:51:17.800801+00:00"}