DEV Community

loading...
Cover image for Ng-magical directives series (ng-container)

Ng-magical directives series (ng-container)

Valentine Awe
I am a Senior Software Engineer with a demonstrated history of working in the financial services industry designing and architecting scalable software applications
Updated on ・3 min read

"Magic is just science that we do not understand yet"
...Arthur C. Clarke

This article is part of what I call the magical directives series. In this series, we will unravel the mystery behind some interesting Angular directives. Afterwards, we can add this little magic to our tool box. I call them magical directives because they play a very important role in building reusable components across our Angular applications.

Below are the directives that we will be looking at in this series.

  • ng-template
  • ng-container
  • ng-content
  • *ngTemplateOutlet
links to other articles in this series are below

The ng-container

The ng-container is a grouping element that does not introduce a new element in the DOM when used in our template. This means that it does not interfere with the layout and style of your application.

The ng-container is mostly used with the structural directives. However, it serves two major purposes:

  1. Removal of redundant elements
  2. Elimination of invalid HTML code

Removal of Redundant Elements

I am pretty sure that almost every Angular developer at some point in their learning stage encountered the below error

code sample

The error is very clear, and it is because we are trying to use two structural directives on the same element. Below is the most common way we try to resolve the error.

sample code

Well, while this is a very smart way to get rid of the error, there is a smarter way. Before we move forward, let us take a look at what is wrong with the above method of resolving the error.

Firstly, carefully look at the DOM below. You will notice that there is an empty div before the actual div that holds our values. This extra div has no purpose in our code, which makes it redundant. Also, this solution does not give you a cleaner DOM tree and depending on the structure of your template you may have to nest your styles in order to style the content of your target div i.e the div that holds the value.

sample code

This is where the ng-container comes into play. Remember we said that the ng-container does not interfere with the layout and style of you application, because it does not introduce a new element. If we replace our redundant div with the ng-container, below is what we will get when we inspect the DOM

sample code

sample code

Isn't that cool?.

Another example is using the ng-container to replace inline elements, which also helps to remove redundant elements and make your styling easier.

<div>
   <span> 
      The world is incomplete without you 
   </span>
</div>

Enter fullscreen mode Exit fullscreen mode

In the code sample above, we have redundant inline element span which just holds a value. We can use the ng-container to eliminate the span by replacing the span with the ng-container

<div>
   <ng-container>
      The world is incomplete without you
   </ng-container>
</div>

Enter fullscreen mode Exit fullscreen mode

Now, If you check the DOM tree, It will exactly look like what we have below

<div> The world is incomplete without you </div>

Eliminating invalid HTML

There are sometimes when we make little mistakes in our template without even knowing. But because the browser is our friend, it does a lot of cleaning up for us so that our mistakes do not reflect on our web pages. A typical example is this.

<ul>
  <div *ngFor="let hero of Heroes">
    <li *ngIf="hero.name !== 'val'">
      {{ hero.powers }}
    </li>
  </div>
</ul>

Enter fullscreen mode Exit fullscreen mode

In the above, we used a div inside a list. The browser will ignore this and will successfully render our template without throwing any error. There are many other scenarios where we might be tempted to do something similar in order to get our logic right, but this is not good practice. The ng-container comes in very handy again in eliminating this. see sample code below

<ul>
  <ng-container *ngFor="let hero of Heroes">
    <li *ngIf="hero.name !== 'val'">
      {{ hero.powers }}
    </li>
  </ng-container>
</ul>

Enter fullscreen mode Exit fullscreen mode

With this, if you inspect your DOM, you will notice that you have your list without the interference of any other element as seen with the previous example when we had the DIV.

Summary

With ng-container, we are sure of having cleaner style sheet and elimination of redundant HTML elements across our applications.

Previous: ng-template
Next: ng-content

Discussion (1)

Collapse
maxkoretskyi profile image
Max Koretskyi

The ng-container is a grouping element that does not introduce a new element in the DOM when used in our template.

Actually it does introduce a new element - a comment node that acts as an anchor for rendered content from a template