Angular’s NgIf
directive doesn’t need to be complicated, yet you’re here because it kind of is. So let’s take it back to basics and uncover NgIf, Else and also the Then syntax to the fullest.
NgIf
allows us to show and hide content based on the state of a piece of data. We simply pass it an expression to evaluate either truthy or falsy - and the content is made created or destroyed based on the result.
Learn all about Angular’s new @if and @else control flow syntax!
Table of contents
What is NgIf?
Before we dive in too deep, let’s learn the concepts behind NgIf, and why it exists.
NgIf
is known as a “behavioral directive”, that allows us to toggle part of a template based on a conditional value.
This conditional would be evaluated similarly to how JavaScript would evaluate an if (condition) {}
statement, converting the value you supply to a truthy or falsy value and progressing accordingly.
Using Angular’s NgIf
The syntax for NgIf starts off simple, we declare the attribute on an element or component and let it work its magic.
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.
Angular will simply add or remove your DOM nodes, mount or remount your components as the expression changes (if it ever does, that’s up to you).
We’ll also cover why we use the asterisk syntax, shortly.
Standard *ngIf in Angular
There are many ways we can use ngIf
, so let’s start by exploring the most basic use case.
Here’s an empty component and a simple Boolean
value of true
:
@Component({
selector: 'app-component',
standalone: true,
template: `
<div>
Welcome back!
</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.
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
:
<!-- 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 can see how easy and clean it is to use ngIf
. Note that the ngIf
used is a lowercase “n” when declared on an element or component.
Let’s move onto some more interesting examples!
*ngIf and Else
One fantastic addition in Angular is the “else” statement. It behaves very similar to a JavaScript if (condition) { } else { }
statement. Nice and simple!
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>
Woah, what’s this whole #loggedOut
syntax? That’s a template variable. You can name template variables as you wish.
Using a template variable means that we can create a reference to a specific template part and then use it elsewhere - in this example we’re supplying it as an “else” value to ngIf
.
We use the <ng-template>
because much like it’s HTML5 counterpart <template>
, it’s also considered “virtual”.
Being “virtual” means the <ng-template>
contents won’t actually exist in the compiled DOM, until it’s needed (you will never see it until Angular renders it).
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.
So, before we continue, where does this *
asterisk come from? Let’s learn some more advanced topics and concepts about Angular and its templating engine.
ngIf and ng-template
If you’ve not yet explored the <ng-template>
syntax of NgIf, then you’re about to learn some amazing new skills. It’s all about sugar syntax. When we do this:
<div *ngIf="isLoggedIn">
Welcome back, friend.
</div>
What’s actually happening is something like this:
<ng-template [ngIf]="isLoggedIn">
<div>
Welcome back, friend.
</div>
</ng-template>
That’s quite a leap if you’ve never seen it before, or perhaps saw it in the documentation once and quickly closed the page.
In essence, Angular will convert our *ngIf
syntax across to the above internally. This tells us more about what’s happening with [ngIf]
, which is the directive being bound with a property binding syntax (square brackets []
).
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
Let’s learn about the “then” syntax with NgIf.
Adopting the then
syntax alongside ngIf
means we can clean up our templates a little and make them a bit more “separate”, this promotes clean code and a nice pattern to work with.
Using the “then” syntax also 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, this comes down to use cases and preferences for what (could be) more advanced use cases:
<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>
Thinking more about our JavaScript, this syntax aligns more with thinking in the flow of ternary statements.
Our thinking above could be converted to:
ngIf = expression ? then : else;
You’ll note that “expression” is never used, it is only there to tell the JavaScript runtime which value to render. The same applies with the ng-container
example I’ve used above - which would mean we don’t render a DOM node until our NgIf expression is evaluated and subsequently rendered.
NgIf or [hidden]?
It’s interesting to note that even though NgIf
“hides” our content, it actually gets completely destroyed by Angular whenever it needs to render or remove the template or component we bind it to.
If we’d like our content to still be visible in the DOM, however remain hidden, then we should introduce the hidden
attribute:
<div [hidden]="!isLoggedIn">
Welcome back, friend.
</div>
This would then allow Angular to add a hidden
attribute if the isLoggedIn
property was true
- we can show the nice message!
You’ll note here that I’ve negated the expression by using the not (!
) operator within the expression.
You could say the hidden
attribute is a more sophisticated style="display: none;"
.
If something is marked hidden, it is hidden from all presentations, including, for instance, screen readers. Read more on MDN about hidden.
*ngIf, Observables and Async Pipe
Another fantastic addition to ngIf
, the async pipe “as” syntax . Learn about this over here in my next post. You’ll learn how to use Observables alongside your new found NgIf knowledge.
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
To learn more techniques, best practices and real-world expert knowledge, I’d highly recommend checking out my Angular courses - they will guide you through your journey to mastering Angular to the fullest!