Angular - 5.12-Access model and DOM with @ViewChild

Local references are perfect to grab a DOM element from within a template, but they are invisible to the TypeScript class. When the component code itself needs to read or manipulate the DOM, Angular gives us @ViewChild(): a decorator that queries the template and exposes either an element reference or a child component instance as a class property.

Two flavours of @ViewChild

  • @ViewChild('localRef') — query a template by its local reference name. The result is an ElementRef wrapping the native DOM element.
  • @ViewChild(ChildComponent) — query by component type. The result is the actual child component instance, so you can read its public state or call its methods.
  • By default the reference resolves after the view is initialised, so reading it inside ngAfterViewInit is the safest option.
@ViewChild('serverNameInput') serverNameInput!: ElementRef<HTMLInputElement>;

onAdd() {
  const value = this.serverNameInput.nativeElement.value;
  console.log(value);
}

Reaching into nativeElement is powerful but should remain the last resort. Direct DOM access bypasses Angular's change detection and breaks server-side rendering. Whenever possible, prefer property and event bindings, or two-way bindings with [(ngModel)]. @ViewChild is the right tool when you need to focus an input, scroll a container into view, integrate with a third-party library, or call a method on a child component such as open() on a modal.

The same idea applies to lists of children with @ViewChildren, and Angular also exposes @ContentChild/@ContentChildren for projected content. The vocabulary is consistent: the View* family targets the component's own template, the Content* family targets what is projected via ng-content.