Lesson Wednesday

In this lesson, we'll explore another common Angular structural directive: ngIf. This directive allows us to embed conditional statements directly inside our templates. We'll use it to dynamically hide and show content in our to do application. Specifically, we'll only show the edit form when a user clicks on the edit button. There will also be a button embedded in the form that allows users to hide the form again.

*ngIf is inserted directly into the HTML template just like other structural directives. Here's an example:

<div *ngIf="property">Content!</div>

It includes a property in quotation marks on the right side of the =. This property is generally a variable defined on the back-end of the component in which the directive resides.

If the property evaluates to true (or the property exists and is not null), the HTML element the directive is bound to will be displayed to the user.

If it evaluates to false (or the property doesn't exist or if its value is null), the HTML element it's bound to will not be rendered in the template.

Adding ngIf to Our Edit Form

Our application always displays an edit form. We can click the edit button of another Task to view a different edit form. However, users probably don't want to see an edit form when they aren't updating a task. Let's update our template so we can hide and show the form.

First, let's redefine our selectedTask property. Instead of defaulting to the first item in our tasks array, let's set it to null. We'll remove this line: selectedTask: Task = this.tasks[0]; and replace it with the following:

app/app.component.ts
...
export class AppComponent {
  ...
  selectedTask = null;
...
}

Here we set the value of selectedTask to null so it won't show on the page. (Note that it won't work until we add our structural directive.)

Next, let's make a few changes to our form in the template:

app/app.component.html
...
<div *ngIf="selectedTask">          
  <h3>{{selectedTask.description}}</h3>
  <p>Task Complete? {{selectedTask.done}}</p>
  <h3>Edit Task</h3>
  <label>Enter Task Description:</label>
  <input [(ngModel)]="selectedTask.description">
  <label>Enter Task Priority (1-3):</label>
  <br>
  <input type="radio" [(ngModel)]="selectedTask.priority" [value]="1">1 (Low Priority)<br>
  <input type="radio" [(ngModel)]="selectedTask.priority" [value]="2">2 (Medium Priority)<br>
  <input type="radio" [(ngModel)]="selectedTask.priority" [value]="3">3 (High Priority)
  <button (click)="finishedEditing()">Done</button>
</div>
...

We've made two changes here. First, we wrap the form in <div *ngIf="selectedTask">. This will ensure that the form shows when there is a selectedTask but remains hidden when the value of selectedTask is null.

Second, we've added an event binding: <button (click)="finishedEditing()">Done</button>. When the button registers a click event, it will run a method called finishedEditing(). Let's define this method now:

app/app.component.ts
...
export class AppComponent {
  ...
  finishedEditing() {
    this.selectedTask = null;
  }
}
...

If you refresh the browser, we can now successfully hide and show the form. Updating the user interface of an Angular application by toggling properties is very common.

Let's do a quick recap. When we load the page, we don't see our edit form because selectedTask is set to null. When we click the edit button, it triggers our editTask method and sets the value of the selectedTask to clickedTask. Now that selectedTask is no longer null, our *ngIf directive evaluates to true and our form shows. We can then hide the form again by triggering our finishedEditing() method, which returns the value of the selectedTask to null.

As you can see, *ngIf offers some pretty useful functionality! By dynamically hiding and showing different areas of your application, you can ensure users are only receiving the information relevant to them.

Try using the *ngIf directive in future projects to add even more interactivity into your application's templates.