Angular ngFor, Of Directive – Lets get tricky!

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 and ngForOf 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 and Even inside ngFor directive?
  • How to use ngFor directive for Nested Arrays or JSON objects in Angular 2+?

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 and ngForOf 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">
<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

instead 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 the student variable outside the element on which we used *ngFor directive.

  <tbody>

<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=""

which connects with the for="" attribute property.
   <div>
<input type="checkbox" id="mycheck">
<label for="mycheck">Selected</label>
</div></pre>
We can use the <strong><code>index
variable inside our ngFor directive
  <div *ngFor="let student of STUDENTS; let i = index"> 

<input type="checkbox" id="mycheck{{i}}">
<label for="mycheck{{i}}">Selected</label>

</div></pre>
 
<h2>How to know which item is <code>First, Last, Odd

and Even 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
*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>subjects

property with each student, which in turn is an Object or could be an Array.

This can be represented by using nested *ngFor directives as shown below:

    <tr *ngFor="let student of STUDENTS">
<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>*ngFor

Angular directive. I hope you enjoyed this quick pick tips tutorial. Do share this with your friends as well if it is helpful.

Thanks for reading!

Leave a Comment

Your email address will not be published. Required fields are marked *