Using ng-container in Angular

Published September 2, 2020

Have you ever written Angular code like this?

<div *ngIf="movies">
  <div *ngFor="let movie of movies">
    <h2>
      {{ movie.title }}
    </h2>
  </div>
</div>

Or, like this?

<div *ngFor="let movie of movies">
  <h2 *ngIf="movie.id">{{ movie.title }}<h2>
</div>

The reason the code is written this way is because we cannot combine *ngIf and *ngFor on one <div> element in Angular. We are unable to use multiple structural directives on a single host element in Angular. Thus, we need to introduce a hierarchy of <div> tags.

The code blocks above work fine but they introduces several extra empty <div> tags in the DOM. As the elements in the DOM start to grow, this can get problematic. Elements might have event listeners attached to them which will still be there in the DOM listening to events even when they are not needed.

The worst part of these code blocks is the level of nesting that you will have to deal with when applying CSS styling to elements.

ng-container to the rescue

Angular's <ng-container> is a grouping element that Angular does not put in the DOM. This means that it will not interfere with styling or layouts.

If you simply need to apply multiple structural directives, such as *ngIf and *ngFor to a code block, use <ng-container> to avoid introducing an extra element in the DOM.

<ng-container *ngIf="movies">
  <div *ngFor="let movie of movies">
    <h2>
      {{ movie.title }}
    </h2>
  </div>
</ng-container>

The <ng-container> element will not render to the page. The only content that will be added to the DOM will be what is inside of the <ng-container> element.