In this post you’ll explore what <ng-container>
is in Angular and when to use it to build better components.
It’s common to want to use a Directive in Angular without generating another element in the DOM. In this post you’re going to learn how to use <ng-container>
to group elements and provide a ‘virtual’ place to bind directives and more.
“Why should you use ng-container?” I hear you ask. Let’s investigate.
First, keeping components nice and lean when rendered has a good impact on DOM performance. Not only this, but using <ng-container>
is clean and seamless to work with. The thing to remember is Angular will never render it to the DOM either, so you can use it as many times as you like.
We don’t want to end up with nested <div>
after <div>
when building components, especially if they are only there for binding things like Directives to and not providing any layout or architecture benefit - which is the perfect use case for <ng-container>
.
Let’s demonstrate with an NgIf
binding:
@Component({
selector: 'pizza-list',
template: `
<div
*ngIf="pizzas.length">
<pizza-item
*ngFor="pizza of pizzas"
[pizza]="pizza">
</pizza-item>
</div>
`,
})
export class PizzaListComponent {}
This works just fine, but creates a <div>
wrapper aroud our <pizza-item>
components. It might not be ideal for us, it litters our rendered markup by creating more elements.
Here’s an example rendered in the DOM:
<pizza-list>
<div>
<pizza-item>...</pizza-item>
<pizza-item>...</pizza-item>
</div>
</pizza-list>
This is where using <ng-container>
comes into play to remove the <div>
wrapper, whilst still providing us the ability to sprinkle some Angular logic.
What is <ng-container>
and how can we use it? You can think of <ng-container>
as “completely virtual” - it never gets rendered in the DOM but looks like an element.
Let’s make the change:
@Component({
selector: 'pizza-list',
template: `
<ng-container
*ngIf="pizzas.length">
<pizza-item
*ngFor="pizza of pizzas"
[pizza]="pizza">
</pizza-item>
</ng-container>
`,
})
export class PizzaListComponent {}
The rendered output when we recompile:
<pizza-list>
<pizza-item>...</pizza-item>
<pizza-item>...</pizza-item>
</pizza-list>
When you’re using things like flexbox as well this technique will be a crucial addition to your toolbox, not to mention it certainly makes your component template more visible and easier to debug.
You can also use as many <ng-container>
elements as you like, and even nest them inside eachother for maximum composition and flexibility of your components.
🚀 Want to learn even more awesome Angular practices?
Check out my new Angular Courses if you’re serious about taking your skills to the top! There’s so much about Standalone Components and all the new best practices in the course.
Thanks for reading, happy containing!