Hey all! today we’ll learn about one of the most popular structural directive *ngFor which is used by an Angular developer a number of times.
The ngFor directive is mainly used to display dynamic data using an Array or Object in a view or HTML template. This Array or Object could be fetched from a remote server or just placed in the client-side code itself.
We’ll start from basic and go ahead to learn new ways the ngFor directive with examples. Following are the pointers which we are going to discuss in this tutorial:
- What is
*ngFor
directive and how it works in Angular? - How to use
ngFor
andngForOf
to display data in the template? - Most common errors we face while using ngFor
- What is the Scope of an item inside the
ngFor
directive element? - How to get the index of each iteration inside the ngFor directive loop?
- How to know which item is
First, Last, Odd
andEven
inside ngFor directive? - How to use ngFor directive for Nested Arrays or JSON objects in Angular 2+?
[lwptoc]
Let’s go ahead with our tutorial to understand and get more proficient with ngFor directive techniques in Angular.
You can continue with your current project or create a new one by hitting below command in the terminal
$ ng new angular-ngfor-tricks ? Would you like to add Angular routing? No ? Which stylesheet format would you like to use? CSS
What is *ngFor
directive and how it works in Angular?
The directives are mainly used to do repetitive tasks on the template. Similarly, *ngFor
is a core directive that allows it to iterate items inside an Array or Object and helps in building list of elements in the HTML template.
The ngFor
directive in Angular 2+ is a substitute to the ng-repeat
directive of Angular 1 or Angular JS
In HTML table rows, ngFor directive loops over or iterate the data in the collection provided.
For example, take a look at the following Array of Object representing STUDENTS
data
STUDENTS = [ { "id": 1, "name": "Brigitte", "age": 17, "marks": 78 }, { "id": 2, "name": "Jordy", "age": 18, "marks": 88 }, { "id": 3, "name": "Terence ", "age": 16, "marks": 97 }, { "id": 4, "name": "Brooklyn", "age": 18, "marks": 69 }, { "id": 5, "name": "Amie", "age": 15, "marks": 92 }, ];</pre> Using the ngFor directive we will iterate the Students information by providing the <code>STUDENTS
data collection in the HTML template in the table as shown below<table> <thead> <tr> <th>Name</th><th>Age</th><th>Marks</th> </tr> </thead> <tbody> <!-- using ngFor on row --> <tr *ngFor="let student of STUDENTS"> <td>{{student.name}}</td> <td>{{student.age}}</td> <td>{{student.marks}}%</td> </tr> </tbody> </table>The
ngFor
directive takes care of the number of items inside the collection and automatically iterates all of them by creating the clone of the element on which it is used. Like here the<tr>
element is cloned as seen inside the template DOM.
How to use
ngFor
andngForOf
to display data in the template?As mention before,
*ngFor
is a structural directive but behind the scenes, it built up of other input properties.So, the example we used above can also be used as shown below
<ng-template ngFor let-student [ngForOf]="STUDENTS">
instead
<tr><td>{{student.name}}</td>
<td>{{student.age}}</td>
<td>{{student.marks}}%</td></tr>
</ng-template></pre>
this will produce the same result as before. Angular provides us with syntactic sugar syntax to ease their usage.
<h2>Most<strong> common errors</strong> we face while using ngFor</h2>
The two most common error which can happen and consume lots of hours to realize they were so silly to make!<strong>1) Using <code>in
of
We may some time face following error when using *ngFor directive
Can't bind to <strong>'ngForIn'</strong> since it isn't a known property of 'tr'
This happens if we use
*ngFor="let student <strong>in</strong> STUDENTS"
instead of*ngFor="let student <strong>of</strong> STUDENTS"
This is a typo mistake we all do number of times because in the ng-repeat directive used to use in Angular js version 1 it was used like this
<tr ng-repeat="student in STUDENTS">...</tr>
2) Need to use
CommonModule
ÂIn Angular applications, which use lazy-loading by having multiple modules for their own components, when we use
*ngFor
we may see an error like this:
Can't bind to <strong>'ngForOf'</strong> since it isn't a known property of 'tr'
To resolve this, you need to import the CommonModule in the submodule's
imports
array. See here for more details.
What is the Scope of an item variable inside the
ngFor
directive element?If we consider our previous example of the
<table>,
we can't use thestudent
variable outside the element on which we used*ngFor
directive.<tbody>
which connects with the<tr *ngFor="let student of STUDENTS">
<td>{{student.name}}</td>
<td>{{student.age}}</td>
<td>{{student.marks}}%</td></tr>
</tbody>
<!-- Hey! I am NOT going to work -->
<div>
Student Name: {{student.name}}
</div></pre>
So if you try to do something like above, it will throw a cute red error! believe me.<img class="wp-image-4316 size-full alignleft" src="https://www.freakyjolly.com/wp-content/uploads/2020/05/Pasted-into-Angular-ngFor-Of-Directive-Lets-get-tricky-1.png" />
<h2>Get the<strong> index of each iteration</strong> inside the ngFor directive loop?</h2>
The index value starts from 0 and gets incremented with each item like an Array. While using *ngFor directive, we may face a situation where we need to get a unique identification for controls inside looped over elements.For example, the following template needs a unique<strong><code> id=""
for=""
attribute property.<div>
variable inside our ngFor directive
<input type="checkbox" id="mycheck">
<label for="mycheck">Selected</label>
</div></pre>
We can use the <strong><code>index<div *ngFor="let student of STUDENTS; let i = index">
and<input type="checkbox" id="mycheck{{i}}">
<label for="mycheck{{i}}">Selected</label></div></pre>
<h2>How to know which item is <code>First, Last, OddEven
inside ngFor directive?Inside of the ngFor directive, other then
index
we can also get other variables
index: number
: The index of the current item in the iterable.count: number
: The length of the iterable.first: boolean
: True when the item is the first item in the iterable.last: boolean
: True when the item is the last item in the iterable.even: boolean
: True when the item has an even index in the iterable.odd: boolean
: True when the item has an odd index in the iterable.
These can be used inside the list as shown below:
<div
property with each student, which in turn is an Object or could be an Array.
*ngFor="let student of STUDENTS;
let index = index;
let count = count;
let first = first;
let last = last;
let even = even;
let odd = odd;"><div>Total Rows: {{count}}</div>
<div>Row Index: {{index}}</div>
<div>Is First: {{first}}</div>
<div>Is Last: {{last}}</div>
<div>Is Even: {{even}}</div>
<div>Is Odd: {{odd}}</div></div></pre>
<h2>How to use ngFor directive for <strong>Nested Arrays or JSON objects</strong> in Angular 2+?</h2>
In scenarios where we have <strong>multi-level or Nested Object</strong>, a nested list of items needs to be built. Let's consider this modified object
<pre class="wp-block-prismatic-blocks"><code class="language-javascript"> STUDENTS = [
{
"id": 1,
"name":
"Brigitte",
"age": 17,
"marks": 78,
"subjects": [
{
"name": "Mathematics"
}, {
"name": "Physics"
}, {
"name": "Chemistry"
}
]
},
{
"id": 2,
"name":
"Jordy",
"age": 18,
"marks": 88,
"subjects": [
{
"name": "Biology"
}, {
"name": "Physics"
}, {
"name": "Chemistry"
}
]
}
];</pre>
Here we have <code>subjectsThis can be represented by using nested
*ngFor
directives as shown below:<tr *ngFor="let student of STUDENTS">
Angular directive. I hope you enjoyed this quick pick tips tutorial. Do share this with your friends as well if it is helpful.
<td>{{student.name}}</td>
<td>{{student.age}}</td>
<td>{{student.marks}}%</td>
<td>
<ul><li *ngFor="let subject of student.subjects">
{{subject.name}}
</li></ul>
</td>
</tr></pre>
<img class="alignnone wp-image-4318 size-full" src="https://www.freakyjolly.com/wp-content/uploads/2020/05/Pasted-into-Angular-ngFor-Of-Directive-Lets-get-tricky-2.png" />
<h2>Conclusion</h2>
That's it! We have discussed many new things related to the <code>*ngForThanks for reading!
Category: Angular
Leave a Reply