Skip to main content

How to use *ngIf else in Angular


How to use *ngIf else in Angular

In this tutorial, we are going to take a look at the ngIf directive.
We will discover how we can use it to show or hide parts of our angular application.
Also, we will find out how the ngIf directive differs from using the "hidden" attribute.

When we got the basics, we will move on to more advanced topics like using the "else"-condition with ng-template and logical operators.
Finally, we will take a look under the hood and see, how angular actually uses the ngIf directive.
Ready?
Let's get started!

What does ngIf do?

NgIf is very useful if you want to show or hide parts of your application based on a condition.
For example, we could have a simple flag inside of our component:
example.component.ts
import { Component } from '@angular/core'

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.css'],
})
export class ExampleComponent {
  show: boolean = true
}
Based on that flag, a certain HTML element is added or removed from the DOM:
example.component.ts
<p>Show this all the time</p>
<p *ngIf="show">Show this only if "show" is true</p>
Also, this condition does also apply to all child elements of the element that has the ngIf directive:
example.component.ts
<p>Show this all the time</p>
<div *ngIf="show"><p>Show this only if "show" is true</p></div>

NgIf is a directive

NgIf is a directive.
That means, that it can be added to any tag in your template. This includes regular HTML-tags like the "p"-tag shown above and even angular component selectors.
<another-component *ngIf="show">
</another-component>

NgIf vs hidden

At first sight, the angular ngIf directive seems to just the same thing as binding to the HTML5 "hidden" attribute. So why do we need two ways to do the same thing?
<p [hidden]="!show">
  Show this only if "show" is true
</p>
Because they actually do two completely different things.
While the hidden attribute is literally hiding the selected part of the DOM, just like the CSS "display: none" property, the element still sit on the DOM. They are just invisible.
Angulars' ngIf directive, on the other hand, is completely removing the selected part from the DOM. The great advantage of that is, that this method is not interfering with any CSS-Style-sheets at all. It is simply removing anything.

Null Check with ngIf

Another very useful application of ngIf is when you need to check if a bound property is null before displaying some of its properties. For example, displaying a box with the users' information wouldn't make much sense if there is no information to display. Normally this would result in an empty box to be shown.
This is an affiliate link. We may receive a commission for purchases made through this link.
With the help of the ngIf directive, we can hide this box altogether, if the corresponding property is null or undefined anyway.

Avoiding "Cannot read property of undefined" errors

The ngIf directive can be very handy to prevent "Cannot read property of undefined" errors, as well.
<p>
  {{user.name}}
</p>
Maybe we are using sub-properties of the bound property. For example the name of the user. Accessing this property if user is undefined will result in an error. But by checking the user-property for null before using its properties will prevent this.
<p *ngIf="user">
  {{user.name}}
</p>
angular-build-banner

Logical operators

The ngIf directive does also support logical operators, just like a regular JavaScript if statement would.

Logical NOT (!)

To invert the boolean value of a variable, we can use the not operator (!). The marked block is then shown when the variable is false.
<p *ngIf="!show">
  Show this only if "show" is NOT true
</p>

Logical AND (&&)

We can also chain two or more statements together using the AND (&&) operator. Again, just like in JavaScript, the statement is only true when all chained values are true, as well.
So the marked block is only shown when all values are true. For example a AND b have to be true:
<p *ngIf="a && b">
  Show this only if a AND b are true
</p>

Logical OR (||)

Just like the AND operator, the OR operator is used to chain one or more statements together. The difference with the OR operator is, that only one statement has to be true for the overall statement to be true, as well.
The marked block is shown, if either a or b is true:
<p *ngIf="a || b">
  Show this only if a AND b are true
</p>
angular-performance-banner

Working with "else"

Just as we are used to from other programming languages, the angular ngFor directive does also allow us to declare an else-block. This block is shown if the statement defined in the main block happens to be false.
<div *ngIf="show; else notShow">
  <p>
    Show this only if "show" is true
  </p>
</div>

<ng-template #notShow>
  <p>
    Show this only if "show" is not true
  </p>
</ng-template>
Notice, that the else block has to be an ng-template. The ng-template is a special element that is interpreted by angular and has no DOM counterpart. That means, that this tag is not included in the final HTML result, but only its content.
We have to use ng-content, because a normal div would be picked up by the browser and be rendered all the time.
Also, we have to give that block an ID (#notShow) so we can reference it in our ngIf directive as the "else"-block.
angular-code-banner

NgIf also has a "then"

In some rare cases, it might be useful to have the ngIf directive from its actual result-block. This would enable us to swap the result of the block out on the fly, by just referencing another ng-template.
For that reason, angulars' ngIf directive also has a then property.
<ng-template
  *ngIf="show;then showBlock; else notShowBlock">
</ng-template>

<ng-template #showBlock>
  <p>
    Show this only if "show" is true
  </p>
</ng-template>

<ng-template #notShowBlock>
  <p>
    Show this only if "show" is not true
  </p>
</ng-template>
However, this is not the common and not the recommended way to do this, unless you really need that dynamic swapping. Personally, I have never used this before.
angular-lock-banner

The hidden syntax of ngIf and ng-template

Last but not least, we are going to take a look under the hood.
It turns out, the sweet syntax with the * asterisk is just syntactic sugar. What this directive does internally, is convert its content to regular binding.
Also, it wraps its content with an additional ng-template.
For example, this template
<p *ngIf="show; else notShow">
  Show this only if "show" is true
</p>

<ng-template #notShow>
  <p>
    Show this only if "show" is not true
  </p>
</ng-template>
is converted to this internally:
<ng-template [ngIf]="show" [ngIfElse]="notShow">
  <p>
    Show this only if "show" is true
  </p>
</ng-template>

<ng-template #notShow>
  <p>
    Show this only if "show" is not true
  </p>
</ng-template>
You can use either of these methods. They have the same result. But notice, that you can save a few lines with the first method.
Personally, I only use the first method and have not seen the second one to be used anywhere.

Conclusion

In this tutorial we discovered, how we can use the power of the ngIf directive in our angular application.

Comments

Popular posts from this blog

4 Ways to Communicate Across Browser Tabs in Realtime

1. Local Storage Events You might have already used LocalStorage, which is accessible across Tabs within the same application origin. But do you know that it also supports events? You can use this feature to communicate across Browser Tabs, where other Tabs will receive the event once the storage is updated. For example, let’s say in one Tab, we execute the following JavaScript code. window.localStorage.setItem("loggedIn", "true"); The other Tabs which listen to the event will receive it, as shown below. window.addEventListener('storage', (event) => { if (event.storageArea != localStorage) return; if (event.key === 'loggedIn') { // Do something with event.newValue } }); 2. Broadcast Channel API The Broadcast Channel API allows communication between Tabs, Windows, Frames, Iframes, and  Web Workers . One Tab can create and post to a channel as follows. const channel = new BroadcastChannel('app-data'); channel.postMessage(data); And oth...

Certbot SSL configuration in ubuntu

  Introduction Let’s Encrypt is a Certificate Authority (CA) that provides an easy way to obtain and install free  TLS/SSL certificates , thereby enabling encrypted HTTPS on web servers. It simplifies the process by providing a software client, Certbot, that attempts to automate most (if not all) of the required steps. Currently, the entire process of obtaining and installing a certificate is fully automated on both Apache and Nginx. In this tutorial, you will use Certbot to obtain a free SSL certificate for Apache on Ubuntu 18.04 and set up your certificate to renew automatically. This tutorial will use a separate Apache virtual host file instead of the default configuration file.  We recommend  creating new Apache virtual host files for each domain because it helps to avoid common mistakes and maintains the default files as a fallback configuration. Prerequisites To follow this tutorial, you will need: One Ubuntu 18.04 server set up by following this  initial ...

Working with Node.js streams

  Introduction Streams are one of the major features that most Node.js applications rely on, especially when handling HTTP requests, reading/writing files, and making socket communications. Streams are very predictable since we can always expect data, error, and end events when using streams. This article will teach Node developers how to use streams to efficiently handle large amounts of data. This is a typical real-world challenge faced by Node developers when they have to deal with a large data source, and it may not be feasible to process this data all at once. This article will cover the following topics: Types of streams When to adopt Node.js streams Batching Composing streams in Node.js Transforming data with transform streams Piping streams Error handling Node.js streams Types of streams The following are four main types of streams in Node.js: Readable streams: The readable stream is responsible for reading data from a source file Writable streams: The writable stream is re...