ng-container
Tags: angular, typescript, javascript, directives
Published: 2021-06-20 11:56:07

"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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/29teiw8t53q4zkxjpk7w.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yy95mi1kvuv2324ymsry.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2hkxjklgyz4vcvh6teso.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v7ekn6ydv6cooht38t8p.png)
 
![sample code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jvc775yrlyive14x12yr.png)

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>

```

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>

```
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>

```

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>

```

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](https://dev.to/valoni01/ng-magical-directives-series-ng-template-41n)
Next: [ng-content](https://dev.to/valoni01/ng-magical-directives-series-ng-content-2gfk)