ng-template
Tags: angular, directives, javascript, typescript
Published: 2021-06-13 16:33:05

> 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


#The ng-template


The _ng-template_ directive simply represent an Angular template. Angular uses the ng-template under the hood in our structural directives( [__*ngIf__](https://angular.io/api/common/NgIf), [__*ngFor__](https://angular.io/api/common/NgForOf)) and [__ngSwitch__](https://angular.io/api/common/NgSwitch). The *ngSwitch* controls the structural directives ([*ngSwitchCase](https://angular.io/api/common/NgSwitchCase) and [*ngSwitchDefault](https://angular.io/api/common/NgSwitchDefault) ) and it is an attribute directive. 

Whenever we use any of these structural directives, Angular does the below.

```
<!-- Your actual code with a structural directive -->

<div *ngIf="food">
  <p>some interesting contents</p>
<div>

<!-- What Angular does behind the scene-->

<ng-template [ngIf]="food">
  <div>
    <p>some interesting contents</p>
  </div>
</ng-template>

```

From the above code sample, Angular sees the `asterisk (*)` in the `*ngIf` and automatically recognizes it as a structural directive. It then wraps the host element inside an `ng-template`, this is the same for other structural directives. What makes it more beautiful is that, Angular comments the `ng-template` directive (as seen in green text in the image below), so the _ng-template_ is never displayed as a tag in the DOM tree.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49ykq57vjcjmc8oo29su.png)

######NB: Angular does not display the content of the ng-template by default. The ng-template only represents a template which you can then decide how you want it to be displayed. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iqcx1fon7wevgiwm7a0o.png)

######_From the image above, Angular converts the `*` into an ng-template which then result to a nested ng-template. Since Angular does not display the content of the ng-template, We will end up with just comments_

If you decide to write your structural directives inside the ng-template, you will just have to replicate what Angular does when it sees a structural directive. E.g for `*ngIf`, it will be `<ng-template [*ngIf]=""> </ng-template>` As seen in the first code sample above. You can do the same for other structural directives and it will work just fine. Below is an example with ngSwitch.

```
<!-- ngSwtich with structural directives *ngSwitchCase and *ngSwitchDefault -->
  
<div [ngSwitch]="food">
    <div *ngSwitchCase="'Beans'"> yeah... Sweet Beans</div>
    <div *ngSwitchCase="'Rice'"> ummm.. Yummy rice</div>
    <div *ngSwitchDefault>No Food Selected</div>
</div>

<!-- ngSwitch with ng-template  -->

<div [ngSwitch]="food">
    <ng-template [ngSwitchCase]="'Beans'"> yeah... Sweet Beans</ng-template>
    <ng-template [ngSwitchCase]="'Rice'"> ummm.. Yummy rice</ng-template>
    <ng-template ngSwitchDefault>No Food Selected</ng-template>
</div>

```
 
Using the ng-template can help remove redundant elements from your DOM tree when necessary. As seen in the code sample with the _ngSwtich_ and _ng-template_, there won't be an extra `div` created in the DOM tree compare to the first sample without the ng-template. Although, it could sometimes be easier and cleaner in most cases to use the `*` i.e instead of wrapping the host inside the ng-template.

But wait, there are other interesting ways that you can utilize the magical effect of the _ng-template_ and one of them is with the **ngIf-else** and **ngIf-else-then**

Let us take for instance that you are working on an application where you want to display a certain template based on a condition. In this case, you can enclose the templates in an _ng-template_ and add a reference to each template so that whenever a certain condition is met, the corresponding template will be displayed as seen in the image below.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ix69vm6e33kixltunamx.png)

A common use case is when you are waiting for a response from the server and you want to temporary display a loader until you receive the response. 

```
<!-- use case for If else -->
<div *ngIf="result else loading">
   <p>{{result}}</p>
</div>


<!-- our loader template -->

<ng-template #loading>
    Loading ...
</ng-template>

```

_Here, the default display will be 'Loading..' until we get the result from the server._

#Summary

The magical effects of the ng-template cannot be over emphasized. In the rest of the series, we will see how to use the ng-template along with the other directives.

Next: [ng-container](https://dev.to/valoni01/ng-magical-directives-series-ng-container-2979)