viewChild() & contentChild()

Reach Into Your Template — Or Your Projected Content

viewChild() & contentChild()

viewChild reads an element or component in your own template; contentChild reads something a parent projected into you.

4 min read Level 3/5 #angular#components#queries
What you'll learn
  • Read with viewChild and viewChildren signals
  • Read projected content with contentChild
  • Use the required variant for guaranteed presence

Most of the time you bind data with property and event binding. Occasionally you need to imperatively grab a DOM element or a child component — that is what query functions are for.

viewChild — Your Own Template

import { Component, ElementRef, viewChild } from '@angular/core';

@Component({
  selector: 'app-login',
  standalone: true,
  template: `<input #emailRef /><button (click)="focus()">Focus</button>`,
})
export class LoginComponent {
  email = viewChild<ElementRef<HTMLInputElement>>('emailRef');

  focus() {
    this.email()?.nativeElement.focus();
  }
}

viewChild() returns a signal. Call it to read; it is undefined until the view has rendered.

Required Variant

If you know the element will always exist, skip the null check.

email = viewChild.required<ElementRef<HTMLInputElement>>('emailRef');
// this.email().nativeElement — no optional chain needed

viewChildren — Multiple Matches

import { viewChildren } from '@angular/core';
import { TabComponent } from './tab.component';

tabs = viewChildren(TabComponent);

activateFirst() {
  this.tabs()[0]?.activate();
}

viewChildren returns a signal of an array, recomputed whenever the matching set changes.

contentChild — Projected Content

contentChild reads markup the parent projected via ng-content.

import { Component, contentChild } from '@angular/core';

@Component({
  selector: 'app-card',
  standalone: true,
  template: `<ng-content />`,
})
export class CardComponent {
  header = contentChild<ElementRef>('header');
}

The parent passes <div #header>Title</div> inside <app-card>, and the card can read it.

Host Bindings & host Config →