30.3. ngIf¶
The *ngIf structural directive evaluates a boolean expression and then
adds or removes elements from the DOM based on the result.
The examples below show the basic usage of *ngIf. If you want to explore
more details about this directive, refer to the following resources:
30.3.1. *ngIf Syntax¶
In general, the syntax for *ngIf is:
*ngIf = "condition"
*ngIf statements are added inside an HTML tag. The condition can either
be a boolean or an expression that returns a boolean. If condition
evaluates to true, then the HTML tag is added to the web page, and the
content gets displayed. If condition returns false, then the HTML tag
is NOT generated, and the content stays off the web page.
Note
*ngIf determines if content is added or removed from a page. This is
different from determining if content should be displayed or hidden.
Hidden content still occupies space on a page and requires some amount of memory. Removed content is absent from the page---requiring neither space on the page nor memory. This is an important consideration when adding items like images or videos to your website.
Example
Let's modify our movie list code as follows:
1 2 3 4 5 6 | <div class='movies' *ngIf = "movies.length > 3">
<h3>Movies to Watch</h3>
<ol>
<li *ngFor = "let movie of movies">{{movie}}</li>
</ol>
</div>
|
Adding the *ngIf statement inside the <div> tag determines whether
that element and any content it contains gets added to the web page. If the
condition movies.length > 3 evaluates to true, then the div,
h3, ol, and li tags all get generated. If the condition returns
false, then none of the tags are added to the HTML code.
Note
Only one structural directive can be assigned to an element. Since the li
tag in the example above already contains *ngFor, we cannot add an
*ngIf statement.
30.3.1.1. Logical Operators With *ngIf¶
Just like if statements, we can use the operators AND (&&), OR
(||), and NOT (!) to modify the condition checked by *ngIf.
Examples
Logical AND:
<p *ngIf = "conditionA && conditionB">Some text</p>
Some text appears on the web page only if conditionA and
conditionB both return true.
Logical OR:
<p *ngIf = "conditionA || conditionB">Some text</p>
Some text appears on the page if either conditionA or conditionB
return true.
Logical NOT:
<p *ngIf = "arrayName.length !== 0">Some text</p>
Some text appears when arrayName.length is NOT equal to 0.
30.3.1.2. What About if/else?¶
With JavaScript, we know how to use an if/else block to decide which set of
code to execute:
1 2 3 4 5 | if (num > 5) {
//Execute this code if num is greater than 5.
} else {
//Execute this code if num is NOT greater than 5.
}
|
We can do the same thing in Angular to decide which set of HTML tags to
generate. Unfortunately, setting this up with *ngIf is not as efficient.
The general syntax for adding an else block in Angular is:
1 2 3 4 5 6 7 | <someTag *ngIf = "condition; else variableName">
<!-- HTML tags and content --->
</someTag>
<ng-template #variableName>
<!-- Alternate HTML tags and content --->
</ng-template>
|
Note that the # is required inside the ng-template tag.
Example
Let's modify the movie list example to create an alternate set of HTML tags
if movies.length > 3 returns false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <div class='movies' *ngIf = "movies.length > 3; else needMoreMovies">
<h3>Movies to Watch</h3>
<ol>
<li *ngFor = "let movie of movies">{{movie}}</li>
</ol>
</div>
<ng-template #needMoreMovies>
<div class='movies'>
<h3>Not Enough Movies!</h3>
<p>You only have {{movies.length}} movies on your watch list!</p>
<p>What's up with that?</p>
<p>You need to purchase expensive popcorn more often.</p>
</div>
</ng-template>
|
In line 1, the condition for *ngIf specifies what to do if
movies.length > 3 returns true or false:
If
true, Angular executes lines 1 - 6.If
false, Angular searches for alternate code labeled with the nameneedMoreMovies. In this case, Lines 9 - 14 hold the alternate HTML tags.
<ng-template></ng-template> is a special Angular element. It contains
content that might be required for a web page. When the else statement in
line 1 executes, Angular searches for an ng-template block labeled with the
matching variable name. Angular then ignores the original div tags and
anything they contain, and it replaces that content with lines 9 - 14.
30.3.2. Try It¶
In VSCode, return to your Angular Lesson 2 project. Use the terminal panel to
commit any changes to your *ngFor work, then switch to the
ngif-practice folder.
$ cd ..
$ ls
input-practice ngfor-practice ngif-practice
$ cd ngif-practice
In VSCode, open the chores.component.html file from the ngif-practice
folder:
The code should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <div class="chores">
<h3>Chores</h3>
<ul>
<li *ngFor = 'let chore of chores'>{{chore}}</li>
</ul>
</div>
<hr>
<div class="doneChores">
<h3>Done Chores</h3>
<ul>
<li *ngFor = 'let done of finishedChores'>{{done}}</li>
</ul>
</div>
<hr>
|
Once again, you must install the necessary Angular modules. Run npm install
in the terminal, then enter ng serve to launch the project.
Now use *ngIf to do the following:
Display the text "Work harder!" under the
Choreslist if the length of thechoresarray is longer than the length of thefinishedChoresarray. Use aptag for the text and make the words a different color.Find the
choresandfinishedChoresarrays inchores.component.tsand modify the number of items. Save your changes and reload the page to verify that your code works.If the
choresarray is empty OR thefinishedChoresarray has at least 3 more items than thechoresarray, displaytargetImageunder theDone Choreslist. Otherwise, use aptag to display the text, "No allowance yet."Return to
chores.component.tsand change the number of items in the arrays again. Check to make sure the web page correctly responds to your changes.Finally, if the
choresarray is empty ANDfinishedChorescontains 4 or more items, display anh1underneath the lists with the text "Ice cream treat!" Otherwise, displayh3andpelements that describe how to earn ice cream.
Properly done, your page should look something like:
30.3.3. Check Your Understanding¶
Examine the following code:
1 2 3 4 5 6 7 8 9 10 | <div>
<h3>Prep Work</h3>
<ul>
<li *ngFor = "let task of prepWork">{{task}}</li>
</ul>
</div>
<ng-template #noHW>
<p>This space intentionally left blank.</p>
</ng-template>
|
Question
Assume we have defined a prepWork array to hold the homework tasks for our
next class. We want the web page to always show the heading. Underneath that
we want to add either the list of tasks or the paragraph text if the array is
empty.
Where should we place an *ngIf statement to make this happen?
In the
divtagIn the
h3tagIn the
ultagIn the
litagIn the
ng-templatetagIn the
ptag
Question
For the same code sample, which of the following shows the correct syntax for
the *ngIf statement?
*ngIf = "prepWork.length === 0; else noHW"*ngIf = "prepWork.length !== 0; else noHW"*ngIf = "prepWork.length === 0; else #noHW"*ngIf = "prepWork.length !== 0; else #noHW"
