DEV Community

Cover image for ng-template
Valentine Awe
Valentine Awe

Posted on • Edited on

ng-template

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, *ngFor) and ngSwitch. The ngSwitch controls the structural directives (*ngSwitchCase and *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>

Enter fullscreen mode Exit fullscreen mode

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

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

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>

Enter fullscreen mode Exit fullscreen mode

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

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>

Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)