@ContentChild normally works with ngAfterContentInit lifecycle.
@ContentChild is used for looking into child component‘s props.
For example, we a app component:
<auth-form (submitted)="loginUser($event)"> <h3>Login</h3> <auth-remember (checked)="rememberUser($event)"> </auth-remember> <button type="submit"> Login </button> </auth-form>
Inside it define a ‘auth-form‘ component, and for auth-form component it has ‘h3‘, ‘auth-remember‘ and ‘button‘ component as children.
Auth-form:
<div> <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> <ng-content select="h3"></ng-content> <label> Email address <input type="email" name="email" ngModel> </label> <label> Password <input type="password" name="password" ngModel> </label> <ng-content select="auth-remember"></ng-content> <ng-content select="button"></ng-content> </form> </div>
Inside auth-form, it use <ng-content> (content projection) to show ‘h3, button & auth-remember‘ component. So what we want to do here is "inside auth-form component, listen to auth-remember‘s checked event, using its value to toggle a message div".
Add a message div:
<div> <form (ngSubmit)="onSubmit(form.value)" #form="ngForm"> <ng-content select="h3"></ng-content> <label> Email address <input type="email" name="email" ngModel> </label> <label> Password <input type="password" name="password" ngModel> </label> <ng-content select="auth-remember"></ng-content> <div *ngIf="showMessage">You account will be kept for 30 days</div> <ng-content select="button"></ng-content> </form> </div>
Using @ContentChild to get the component object.
import { Component, Output, EventEmitter, AfterContentInit, ContentChild } from ‘@angular/core‘; import { User } from ‘./auth-form.interface‘; import {AuthRememberComponent} from ‘./auth-remember.component‘; @Component({ selector: ‘auth-form‘, template: ` ... ` }) export class AuthFormComponent implements AfterContentInit{ showMessage: boolean; @ContentChild(AuthRememberComponent) remember: AuthRememberComponent; @Output() submitted: EventEmitter<User> = new EventEmitter<User>(); onSubmit(value: User) { this.submitted.emit(value); } ngAfterContentInit(): void { if(this.remember) { this.remember.checked.subscribe((checked: boolean) => { this.showMessage = checked; }) } } }
If we check ‘this.remember‘:
We can subscribe ‘this.remember.checked‘ to get whether ‘auth-remember‘ is checeked or not, and assign the value to ‘showMessage‘ var.
@ContentChild is really powerful, it can get any props on the child component.
For exmaple, we can add an @Input value and a private prop on to the auth-remember component.
import { Component, Output, EventEmitter, Input } from ‘@angular/core‘; @Component({ selector: ‘auth-remember‘, template: ` <label> <input type="checkbox" (change)="onChecked($event.target.checked)"> Keep me logged in </label> ` }) export class AuthRememberComponent { @Output() checked: EventEmitter<boolean> = new EventEmitter<boolean>(); @Input() role: string; myName: string = "Auth-remember"; onChecked(value: boolean) { this.checked.emit(value); } }
And from the console log, we can see, we get everthing about the auth-remember component.