Angular's NgIf, Else, Then - Explained

Angular Tagged in Angular Jan 11, 2018 4 mins read by Todd Motto

Using the ngIf directive allows us to simply toggle content based on a conditional. But is it as simple as we think? Not quite, the directive has a heap of helpful syntaxes that can help us deal with conditionals far better, and also asynchronous objects coming from perhaps an Observable.

Let’s explore the ins and outs of ngIf, and how we can utilise (the right way) in our Angular apps.

Angular’s ngIf

Placing the ngIf directive on a component, or element, will in fact hide or show that element based on the expression you pass it to be evaluated. Once evaluated, Angular will simply add or remove your DOM nodes, mount or remount your components, from the DOM - as the expression changes (if it ever does, that’s up to you).

When using an ngIf on a component, this will in turn invoke relevant lifecycle hooks such as ngOnInit, ngOnDestroy, and so forth.

The basic syntax of the ngIf directive is simple and effective, all we need to do is prefix the directive name with an asterisk (*) and add it anywhere inside our template. We’ll cover why we use the asterisk syntax, shortly.

Standard *ngIf in Angular

There are four main ways we can use ngIf, so let’s start by exploring the most basic use case:

@Component({
  selector: 'app',
  template: `
    <div *ngIf="isLoggedIn">
      Welcome back. Congrats.
    </div>
  `,
})
export class AppComponent {
  isLoggedIn = true;
}

We can also use JavaScript-like expressions to achieve a final truthy/falsy value to supply to ngIf - as well as composing through multiple variables through various operators:

<!-- negated variable to achieve "if not" -->
<div *ngIf="!isLoggedIn">
  Please login, friend.
</div>

<!-- logic && operator -->
<div *ngIf="isLoggedIn && !isNewUser">
  Welcome back, friend.
</div>

<!-- logic OR operator -->
<div *ngIf="isLoggedIn || isNewUser">
  Welcome!
</div>

Just a few examples, but I’m sure you catch my drift on the available ways we can compose an ngIf. Let’s move onto some more interesting examples.

*ngIf and Else

One fantastic addition in Angular (coming from an AngularJS background), is the “else” statement. If this, else that. Nice and simple. In AngularJS we’d have to negate the expression to evaluate to an “else”, and templates became a little messy at times. Or we had ng-show and ng-hide directives to get our point across

Thankfully, we have if/else to save us.

Here’s how we can use the “else” statement, to control the render flow inside a component’s template:

<div *ngIf="isLoggedIn; else loggedOut">
  Welcome back, friend.
</div>

<ng-template #loggedOut>
  Please friend, login.
</ng-template>

This setup can also be used to conditionally mount/unmount components as well.

The main two things worth noticing here are the template reference variable (the #loggedOut - which you can call whatever you like) and also the <ng-template>. We use the <ng-template> because much like it’s HTML5 counterpart <template>, it’s also considered “virtual”.

<ng-template> was inspired by <template>, and existed in Angular v2-v4 as just <template>. It’s now deprecated in favour of <ng-template>.

Being “virtual” means the <ng-template> contents won’t actually exist in the compiled DOM, until it’s needed. When it’s needed (for example the “else” expression kicks into play), Angular will grab the contents of the <ng-template> tag, and replace the *ngIf contents with it.

That’s it. It’s just a virtual container that won’t render any contents until it’s ready.

So, before we continue, where does this * asterisk come from?

ngIf and ng-template

It’s all about sugar syntax. When we do this:

<div *ngIf="isLoggedIn">
  Welcome back, friend.
</div>

With our new found knowledge, we can now understand that it’s equivalent to this:

<ng-template [ngIf]="isLoggedIn">
  <div>
    Welcome back, friend.
  </div>
</ng-template>

Angular will convert our *ngIf syntax across to the above, which I’m sure you’ll agree isn’t quite as fast to work with. It does however tell us more about what’s happening with [ngIf], which is the directive being bound with a property binding syntax.

Yes, this does mean, we can supply ngIf, ngIfElse (and ngIfThen) the same way:

<ng-template [ngIf]="isLoggedIn" [ngIfElse]="loggedOut">
  <div>
    Welcome back, friend.
  </div>
</ng-template>

<ng-template #loggedOut>
  <div>
    Please friend, login.
  </div>
</ng-template>

But let’s not skip too far ahead, we’ve not covered ngIfThen just yet…

*ngIf, Then and Else

Adopting then alongside ngIf is simply moving our initial *ngIf template, outside of the element we’re binding to. This creates more flexibility in some use cases, where we can dynamically change the template reference to then - essentially swapping <ng-template> on the fly. A less common use case however.

You could optionally adopt this approach to create a more descriptive if/then/else block. Again, use cases and preferences.

<ng-container
  *ngIf="isLoggedIn; then loggedIn; else loggedOut">
</ng-container>

<ng-template #loggedIn>
  <div>
    Welcome back, friend.
  </div>
</ng-template>
<ng-template #loggedOut>
  <div>
    Please friend, login.
  </div>
</ng-template>

This syntax aligns more with thinking in the flow of ternary statements. Our thinking could be converted to:

ngIf = expression ? then : else;

We could opt for ng-container in this scenario, perhaps we don’t want to render a DOM node until our template is rendered.

Also, when using the then block, any content between the opening and closing tags of the bound element (in the case of above, <ng-container>), all inner content is ignored.

*ngIf, Observables and Async Pipe

Another fantastic addition to ngIf, the async pipe “as” syntax. Learn about this over here in my next post.

Angular Online Courses Angular shields
Ultimate Angular

Become an Angular expert

Online courses that give you the knowledge to master Angular and build real world applications.

Explore Courses Navigation arrow