Angular Structural Directives, Part 1: NgIf
Published: 2021-03-16 14:23:11

Michi DeWitt | ng-conf | Oct 2020

_This is first part of an ongoing series covering all the built-in Angular structural directives. This series is intended for new and experienced Angular developers._

---

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

### **Introduction**
Welcome to Part 1 of our series on built-in structural directives in Angular applications! In this series, we are going to cover what structural directives are and provide a guide on how to use each of the built-in structural directives.

### **What are Structural Directives?**
Structural directives allow a developer to manipulate the DOM in specific ways. This manipulation is done by adding, removing, or changing elements on the page. A structural directive is added as an attribute to an HTML element in a template. Only one structural directive can be added to each element and the directive should always be prefixed with an `*` to make them easy to distinguish from other attributes on the element.

Angular comes with several built-in directives that can be used to control the DOM. Most directives work by manipulating the DOM based on values in the component. They are useful in dynamic applications where the page content often changes based on component values and/or user actions. It can be hard to have dynamic content with vanilla HTML and Javascript, but with Angular’s structural directives, it’s a breeze!

_Note: We’ll only be focusing on the built-in directives in this series, but developers can also build their own custom structural directives as well._

### **How Do I Use Structural Directives?**
To make use of a structural directive, the directive is simply added as an attribute on any element in an Angular template. The structural directive attribute is prefixed by the `*`.

Example:

```
<div *someDirective class="my-class" (click)="doSomething()"></div>
```

In the snippet above, the structural directive `someDirective` is easy to distinguish on the `div` element because of the `*` prefix.

A directive may also bind to properties in the component.

Example:

```
<div *someOtherDirective="someProperty" class="my-class" 
(click)="doSomething()"></div>
```

In the snippet above, the structural directive `someOtherDirective` is bound to the component property `someProperty`.

In this post, we’ll be covering one of the most commonly used directives — `ngIf`.

---

### **What is the NgIf Directive and How is it Used?**
The `ngIf` directive is used to conditionally add or remove elements from the DOM. This is much more powerful than simply showing and hiding elements because you are able to:

1. Only initialize components when they are needed
2. Destroy components when they are no longer needed
3. Not add expensive components when they are not needed

The syntax of the `ngIf` directive is very similar to a conditional if-statement in Javascript which makes it easy and intuitive for developers to use. (It is also almost identical to the `ngIf` directive in AngularJS).

Here are some situations this directive is particularly useful for:

* You want to add/remove content based on the action of a user
* You want to add/remove content based on some configuration value
* You want to add/remove content based on one or more values in the component

### **Basic Usage:**

```
<div *ngIf="someCondition">
  I want to show this if someCondition is truthy!
</div>
```

The `ngIf` directive is added as an attribute on any element you want to conditionally add to the DOM. The directive binds to a condition and the value of that condition is used to determine if the element is added or removed.

When the component is first initialized, the value of any `ngIf` condition is checked and the following will occur:

* If the condition evaluates to `truthy`, the element is _added_ to the DOM
* If the condition evaluates to `falsy`, the element is _not added_ to the DOM

Simple as that!

If the condition changes as the result of change detection, the element the Angular directive was applied to will be appropriately _removed_ or _added_ to the DOM based on the new conditional value.

Let’s highlight the most important part again because the power of the `ngIf` directive can be subtle.

> ### When the NgIf condition evaluates to `falsy`, the element is not hidden in the DOM. It is removed completely — or never added in the first place.

For a small piece of text in a page, this may seem inconsequential. But when combined with more expensive components, you can see large performance implications (both good and bad).

The condition for the `ngIf` directive can either be bound directly to a property in the component.

Example:

```
*ngIf="someProperty"
```

Or the condition can be bound to a boolean expression.

Example:

```
*ngIf="someProperty !== undefined"
```

One reason the `ngIf` directive is easy to use is because it maps closely to the if-statement Javascript syntax many Angular developers are already familiar with. You can mentally map the HTML syntax above to:

```
if (someCondition) {
  // Execute the code in this block
}
```

**Else Block**

Often, you will want to display a different template if the condition in your `ngIf` directive is `falsy`. You may be tempted to add a second `ngIf` directive that explicitly checks if the same condition is `falsy`…

```
<div *ngIf="someCondition">
  If someCondition is truthy, show this
</div>

<!-- Avoid! This is an anti-pattern. -->
<div *ngIf="!someCondition">
  Otherwise I want to show this
</div>
```

But there is a better way!

```
<div *ngIf="someCondition; else otherBlock">
  If someCondition is truthy, show this
</div>

<ng-template #otherBlock>
  Otherwise I want to show this
</ng-template>
```

Like a traditional if-statement in Javascript, you can specify that a different template should be added in the case the condition in the `ngIf` directive is `falsy`.

But why is this better?

1. First, this provides a clean, easy to understand logical flow in your template.
2. This keeps your conditional logic in one place. With the anti-pattern shown above, if you change the `ngIf` condition in one location, you must change it in both. This is brittle and error-prone.
3. You can add the `ng-template` anywhere that makes sense in your HTML template. It does not need to be directly underneath the `ngIf` directive. This gives you more control over how you want to organize your template.

Again, conceptually, this is very similar to the if-else-statement syntax most Angular developers are already familiar with.

```
f (someCondition) {
  // Execute this code block
} else {
  // Execute this other block
}
```

### **Storing NgIf Value**
It’s not uncommon to need to use the result of the `ngIf` condition in multiple places in your template. This is very common when the `ngIf` condition is bound to an Observable using the `async` pipe.

One option is to add the condition in the all locations where the result of the `ngIf` condition is needed…

```
<div *ngIf="tableData$ | async">
  My Conditional Table
  <my-table-component [data]="tableData$ | async"></my-table-component>
</div>
```

But again — there’s a better way!

```
<div *ngIf="tableData$ | async">
  My Conditional Table
  <my-table-component [data]="tableData$ | async"></my-table-component>
</div>
```

The `as` syntax allows you to store the result of the condition as a local variable in the template. Now the value is available to easily re-use elsewhere in the template.

But why is this better?

1. Again, this provides a clean, easy to understand logical flow in your application.
2. Again, this keeps your conditional logic in one place.
3. You do not need to create a second subscription to the `tableData$` Observable.

---

### **Summary**
And that’s everything you need to know about the `ngIf` directive!

Let’s go over the main points again:

🛠 Structural directives provide easy ways for Angular developers to control the DOM based on data in a component

🏗 Structural directives can be added to any element in an Angular template.

🎯 The `ngIf` directive allows you to control the DOM based on a conditional value you bind directly to the directive

➕ When the `ngIf` condition is `truthy` the element will be added to the DOM

➖ When the `ngIf` condition is `falsy` the element will be remove from the DOM

💪 Use the `else` and `as` syntax to take full advantage of all the features provided by the Angular team

## **ng-conf: The Musical is coming**
ng-conf: The Musical is a two-day conference from the ng-conf folks coming on April 22nd & 23rd, 2021. Check it out at [ng-conf.org](https://www.2021.ng-conf.org/)

---

### **Additional Thoughts & Resources**
* Angular Structural Directive Docs: https://angular.io/guide/structural-directives#structural-directives
* Angular `*ngIf` Docs: https://angular.io/api/common/NgIf
* In many examples in this blog, the only reason I added a `div` to the code was to attach a structural directive. In this case, it is often better to use `<ng-container *ngIf="someCondition"></ng-container>` so an extra div is not added to the DOM. We’ll have more on this later in the series.