Log in to like this post! What Is ViewChild and ContentChild in Angular? Dhananjay Kumar / Tuesday, February 6, 2018 (Last Updated: 08.09.2023) ViewChild and ContentChild in Angular are used for component communication. For example, if parent Angular components want access to child components, they use ViewChild or ContentChild. In this blog post, then, we will explain the essence of Angular ViewChild and Angular ContentChild and show you how to use them in your app. Key article pillars: What is ViewChild in Angular Using MessageComponent Changing the value of MessageComponent Working with ViewChildren and QueryList What is ContentChild in Angular Passing MessageComponent Working with ContentChildren and QueryList Wrap up What Is ViewChild in Angular Angular ViewChild or ViewChildren decorators are used to get reference to a component instance by querying the template using the component reference name or class name. ViewChild in Angular returns the first matching component and ViewChildren returns all the matching components as a QueryList of items. We can use these references to work with the component class or its DOM element. If you want to access the following inside the Parent Component, use @ViewChild decorator in Angular. Using MessageComponent Let's assume that we have a MessageComponent as shown in the listing below: import { Component, Input } from '@angular/core'; @Component({ selector: 'app-message', template: `<h2>{{message}}</h2>` }) export class MessageComponent { @Input() message: string; } We are using MessageComponent inside AppComponent as shown in here: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div> <h1>Messages</h1> <app-message [message]='message'></app-message> </div>` }) export class AppComponent implements OnInit { message: any; ngOnInit() { this.message = 'Hello World !'; } } The MessageComponent will be located inside the template of AppComponent. Therefore, we can access it as a ViewChild. export class AppComponent implements OnInit, AfterViewInit { message: any; @ViewChild(MessageComponent) messageComponent: MessageComponent; ngAfterViewInit() { console.log(this.messageComponent); } ngOnInit() { this.message = 'Hello World !'; } } Changing The Value of MessageComponent Now, let's try to change the value of the MessageComponent property. ngAfterViewInit() { console.log(this.messageComponent); this.messageComponent.message = 'Passed as View Child'; } Here, we are changing the value of the ViewChild property. Working With Angular ViewChildren and QueryList We are using MessageComponent inside a *ngFor directive; hence, there are multiple references to MessageComponent. We can access it now as ViewChildren and QueryList, as shown in the listing below: @ViewChildren(MessageComponent) messageComponent: QueryList<MessageComponent>; ngAfterViewInit() { console.log(this.messageComponent); } In the output, you will get various references of MessageComponent as ViewChildern. Now let us try to update the properties of ViewChildren as shown in the listing below: ngAfterViewInit() { console.log(this.messageComponent); this.messageComponent.forEach((item) => { item.message = 'Infragistics'; }); } As you see, we are iterating through each item of Angular ViewChildren and updating each property. This will update the property value but again, you will get the error, “Expression has changed after it was last checked.” You can fix it by manually calling change detection like ViewChild. Keep in mind that we do not have ViewChildren reference available in AfterContentInit life cycle hook. You will get undefined in ngAfterContentInit() life cycle hook for ViewChildren reference as shown in the listing below : ngAfterContentInit() { console.log(this.messageComponent); // undefined } However, you can manually call change detection to fix error: “Expression has changed after it was last checked” To use a change detection mechanism Import ChangeDetectorRef from @angular/core Inject it to the constructor of Component class Call detectChanges() method after ViewChild property is changed You can use a manual change detection like shown in below listing: @ViewChildren(MessageComponent) messageComponent: QueryList<MessageComponent>; constructor(private cdr: ChangeDetectorRef) { } ngAfterViewInit() { console.log(this.messageComponent); this.messageComponent.forEach((item) => { item.message = 'Infragistics'; }); this.cdr.detectChanges(); } What is ContentChild in Angular? The Angular ContentChild property decorator is very similar to the ViewChild and again provides a powerful way to interact with and manipulate projected content within a component. Using it, you can easily get the reference to the Projected Content in the DOM. Let us start with understanding about ContentChild. Any element that is located inside the template is ContentChild. To understand it, let's consider MessageContainerComponent. import { Component } from '@angular/core'; @Component({ selector: 'app-messagecontainer', template: ` <div> <h3>{{greetMessage}}</h3> <ng-content select="app-message"></ng-content> </div>` }) export class MessageContainerComponent { greetMessage = 'Ignite UI Rocks!'; } In this component, we are using Angular Content Projection. You can learn more about the content projection here. Passing MessageComponent in Angular ContentChild Any element or component projected inside <ng-content> becomes a ContentChild. If you want to access and communicate with MessageComponent projected inside MessageContainerComponent, you need to read it as a ContentChild. Before we go ahead and learn to use ContentChild in Angular, first check out how MessageContainerComponent is used and how is MessageComponent is projected, import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div> <app-messagecontainer> <app-message [message]='message'></app-message> </app-messagecontainer> </div>` }) export class AppComponent implements OnInit { message: any; ngOnInit() { this.message = 'Hello World !'; } } As you can see in the listing above, we use MessageContainerComponent in the AppComponent and pass MessageComponent to be projected inside it. Since MessageComponent is used in MessageContainerComponent with content projection, it becomes Angular ContentChild. Since MessageComponnet is projected and being used inside the template of MessageContainerComponent, it can be used as ContentChild, as shown below: import { Component, ContentChild, AfterContentInit } from '@angular/core'; import { MessageComponent } from './message.component'; @Component({ selector: 'app-messagecontainer', template: ` <div> <h3>{{greetMessage}}</h3> <ng-content select="app-message"></ng-content> </div>` }) export class MessageContainerComponent implements AfterContentInit { greetMessage = 'Ignite UI Rocks!'; @ContentChild(MessageComponent) MessageComponentContentChild: MessageComponent; ngAfterContentInit() { console.log(this.MessageComponentContentChild); } } We need to do the following tasks: Import ContentChild and AfterContentInit from @angular/core. Implement AfterContentInit life cycle hook to component class. Create a property with decorator @ContentChild. Access that inside ngAfterContentInit life cycle hook. You can modify the ContentChild property inside the ngAfterContentInit life cycle hook of the component. Let's assume that there is more than one MessageComponent projected as shown in the listing below: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-root', template: ` <div> <app-messagecontainer> <app-message *ngFor='let m of messages' [message]='m'></app-message> </app-messagecontainer> </div>` }) export class AppComponent implements OnInit { messages: any; ngOnInit() { this.messages = this.getMessage(); } getMessage() { return [ 'Hello India', 'Which team is winning Super Bowl? ', 'Have you checked Ignite UI ?', 'Take your broken heart and make it to the art' ]; } } Now we have more than one ContentChild, so we need to access them as ContentChildren as shown in the listing below: export class MessageContainerComponent implements AfterContentInit { greetMessage = 'Ignite UI Rocks!'; @ContentChildren(MessageComponent) MessageComponentContentChild: QueryList<MessageComponent>; ngAfterContentInit() { console.log(this.MessageComponentContentChild); } } Working With ContentChildren and QueryList To work with ContentChildren and QueryList, you need to do following tasks: Import ContentChildren , QueryList , AfterContentInit from @angular/core. Create a property with decorator @ContentChildren with type QueryList. Access ContentChildren reference in ngAfterContentInit() life cycle hook. You can query each item in ContentChildren and modify the property as like this: ngAfterContentInit() { this.MessageComponentContentChild.forEach((m) => m.message = 'Foo'); } And this is how you can work with ContentChildren in Angular. Wrap Up ViewChild and ContentChild are two very important features of Angular. They are used to enable access to the Child Component in the Parent Component. Any directive, component, and element that is part of the component template is accessed as ViewChild. On the other hand, any element or component that is projected inside <ng-content> is accessed as ContentChild. To simplify ViewChild and ContentChild in Angular even more, you can try our full-featured Ignite UI for Angular components library. It provides the fastest Angular data grid and 60+ high-performance charts, empowering you to build modern-day, high-performance Angular apps easily.