Introduction
ng-container
is an element available in Angular 2+ that can act as the host to structural directives.
In this article, you will explore scenarios that can be addressed with ng-container
.
Prerequisites
If you would like to follow along with this article, you will need:
Familiarity with the structure of the DOM. To learn more, check out the tutorial series Understanding the DOM.
Some familiarity with Angular templates and structural directives may also be helpful.
Using ng-container
to Avoid Redundant Elements
In Angular, you cannot use more than one template binding on an element.
This example combining *ngIf
and *ngFor
structural directives will not compile:
Invalid Example<div *ngIf="todos" *ngFor="let todo of todos">
{{ todo.content }}
</div>
Attempting to compile this code will result in the following error:
Invalid Example Can't have multiple template bindings on one element. Use only one attribute prefixed with *
One workaround would be to separate the template bindings and create a wrapper:
Valid Example<div *ngIf="todos">
<div *ngFor="let todo of todos">
{{ todo.content }}
</div>
</div>
One downside is that this approach is it introduces a redundant div
element to the DOM:
Valid Example <div>
<div>
Todo Content 1
</div>
<div>
Todo Content 2
</div>
<div>
Todo Content 3
</div>
</div>
This is where the ng-container
element becomes useful.
The following behaves exactly the same, but without adding any extra element to the DOM at runtime:
Improved Valid Example<ng-container *ngIf="todos">
<div *ngFor="let todo of todos">
{{ todo.content }}
</div>
</ng-container>
This would result in the following markup:
Improved Example <div>
Todo Content 1
</div>
<div>
Todo Content 2
</div>
<div>
Todo Content 3
</div>
ng-container
is also useful in situations where ngIf
is used on inline content:
Example<div>
<span *ngIf="error">Oops:</span> {{ message }}
</div>
If error
is true, this would result in the following markup:
Example <div>
<span>Oops:</span> An error occurred.
</div>
Replacing the span
element with an ng-container
will reduce redundant span
elements added to the DOM:
Improved Example<div>
<ng-container *ngIf="error">Oops:</ng-container> {{ message }}
</div>
If error
is true, this would result in the following markup:
Improved Example <div>
Oops: An error occurred.
</div>
Reducing the amount of markup in your application ultimately results in a smaller DOM tree and can help avoid side effects with Cascading Style Sheet selectors.
Using ng-container
to Ensure Valid HTML Standards
ng-container
can also resolve the problem of invalid HTML markup in situations where using a div
or span
would not be valid HTML.
The following example would produce invalid HTML because li
elements are expected to the be the direct children of the ul
element:
Invalid Example<ul>
<div *ngFor="let todo of todos">
<li *ngIf="todo.content !== 'Done'">
{{ todo.content }}
</li>
</div>
</ul>
Replacing the div
with an ng-container
resolves this issue:
Valid Example<ul>
<ng-container *ngFor="let todo of todos">
<li *ngIf="todo.content !== 'Done'">
{{ todo.content }}
</li>
</ng-container>
</ul>
Having valid HTML will satisfy stricter tests and requirements and ensure support across browsers and devices.
Conclusion
In this article, you explored the problems that ng-container
addresses in your Angular applications, like redundant elements and invalid HTML standards.
If you’d like to learn more about Angular, check out our Angular topic page for exercises and programming projects.