ngFor Directive with Local Variables And trackBy In Angular 2

There are couple of local variables with ngFor built-in structural directive provided by Angular 2, which are used for getting the index of current element while iteration and for getting last or first element from the collection etc. as mentioned below –

  1. Index – Used for provide the index for current element while iteration.
  2. First – Return true if current element is first element in the iteration otherwise false.
  3. Last – Return true if current element is last element in the iteration otherwise false.
  4. Even – Return true if current element is even element based on index in the iteration otherwise false.
  5. Odd – Return true if current element is odd element based on index in the iteration otherwise false.

Let’s understand all these local variables with the help of an example –

Here, I am using the same student application which I used in my previous article for *ngFor directive. Look at my previous article on *ngFor directive.

Index with *ngFor directive

Index gives the index of current element in the iteration. Let’s look into example below. I have a list of students which I am displaying in table on web page as below. Now, I want to add one more column of index at first position, which will represent of index value of each item like below,

Angular

Let’s add the code for displaying the index of the current item in student.component.html file and run it for the expected output – (highlighted code)

  1. <table>  
  2.     <thead>  
  3.         <tr>  
  4.             <th>Index</th>  
  5.             <th>Student ID</th>  
  6.             <th>Name</th>  
  7.             <th>Gender</th>  
  8.             <th>Age</th>  
  9.             <th>Course</th>  
  10.         </tr>  
  11.     </thead>  
  12.     <tbody>  
  13.         <tr *ngFor="let s of students;let i=index">  
  14.             <td>{{i}}</td>  
  15.             <td>{{s.studentID}}</td>  
  16.             <td>{{s.studentName}}</td>  
  17.             <td>{{s.gender}}</td>  
  18.             <td>{{s.age}}</td>  
  19.             <td>{{s.course}}</td>  
  20.         </tr>  
  21.     </tbody>  
  22. </table>  

Output

Angular

First & Last with *ngFor directive

First & Last both provides the Boolean value. Returns true if current element value is first element or last element otherwise false. Let’s look into highlighted code & example below,

  1. <th>Course</th>  
  2. <th>First Element</th>  
  3. <th>Last Element</th>  
  4. </tr>  
  5. </thead>  
  6. <tbody>  
  7.     <tr *ngFor="let s of students;let i=index;let f=first;let l=last">  
  8.         <td>{{i}}</td>  
  9.         <td>{{s.studentID}}</td>  
  10.         <td>{{s.studentName}}</td>  
  11.         <td>{{s.gender}}</td>  
  12.         <td>{{s.age}}</td>  
  13.         <td>{{s.course}}</td>  
  14.         <td>{{f}}</td>  
  15.         <td>{{l}}</td>  
  16.     </tr>  
  17. </tbody>  
  18. </table>  

Output

Angular

Even & Odd with *ngFor directive

Even & odd both provides the Boolean value. Returns true if current element value is even element based on index or odd element based on index, otherwise false. Let’s look into highlighted code & example below,

  1. <th>Last Element</th>  
  2. <th>Even Element</th>  
  3. <th>Odd Element</th>  
  4. </tr>  
  5. </thead>  
  6. <tbody>  
  7.     <tr *ngFor="let s of students;let i=index;let f=first;let l=last;let ev=even;let od=odd">  
  8.         <td>{{i}}</td>  
  9.         <td>{{s.studentID}}</td>  
  10.         <td>{{s.studentName}}</td>  
  11.         <td>{{s.gender}}</td>  
  12.         <td>{{s.age}}</td>  
  13.         <td>{{s.course}}</td>  
  14.         <td>{{f}}</td>  
  15.         <td>{{l}}</td>  
  16.         <td>{{ev}}</td>  
  17.         <td>{{od}}</td>  
  18.     </tr>  
  19. </tbody>  
  20. </table>  

Output

Angular

trackBy with *ngFor directive

To iterate over a collection in Angular 2, I used *ngFor directive in above example.

Let’s understand with the same example why we needed trackBy function with *ngFor directive,

Suppose we have some data coming from some API request into the collection and we need to change the data over the web page using ngFor directive. In this case, Angular 2 will remove all the DOM elements that associated with the data and will create them again in the DOM tree, even the same data is coming (as shown in below screenshot). That means a lot of Dom manipulations will happen if a large amount of data coming from the API.

Angular

The solution is, we can use trackBy function, which will be helpful for Angular to track the items which have been added or removed.

TrackBy function will take two arguments first is index and second is current item and we can return the unique identifier as a return argument.

Let’s add the below function into student.component.ts file and look now,

  1. trackByStudentID(index: number, student: any): string {  
  2.     return student.studentID;  
  3. }  

Updated student.component.ts code file,

  1. export class StudentListComponent {  
  2.     students: any[];  
  3.     constructor() {  
  4.         this.students = [{  
  5.             studentID: 1,  
  6.             studentName: 'Steve',  
  7.             gender: 'Male',  
  8.             age: 35,  
  9.             course: 'MCA'  
  10.         }, {  
  11.             studentID: 2,  
  12.             studentName: 'Bobby',  
  13.             gender: 'Male',  
  14.             age: 32,  
  15.             course: 'MBA'  
  16.         }, {  
  17.             studentID: 3,  
  18.             studentName: 'Rina',  
  19.             gender: 'Female',  
  20.             age: 45,  
  21.             course: 'B.Tech'  
  22.         }, {  
  23.             studentID: 4,  
  24.             studentName: 'Alex',  
  25.             gender: 'Female',  
  26.             age: 24,  
  27.             course: 'M.Tech'  
  28.         }, ];  
  29.     }  
  30.     getStudents(): void {  
  31.         this.students = [{  
  32.             studentID: 1,  
  33.             studentName: 'Steve',  
  34.             gender: 'Male',  
  35.             age: 35,  
  36.             course: 'MCA'  
  37.         }, {  
  38.             studentID: 2,  
  39.             studentName: 'Bobby',  
  40.             gender: 'Male',  
  41.             age: 32,  
  42.             course: 'MBA'  
  43.         }, {  
  44.             studentID: 3,  
  45.             studentName: 'Rina',  
  46.             gender: 'Female',  
  47.             age: 45,  
  48.             course: 'B.Tech'  
  49.         }, {  
  50.             studentID: 4,  
  51.             studentName: 'Alex',  
  52.             gender: 'Female',  
  53.             age: 24,  
  54.             course: 'M.Tech'  
  55.         }, {  
  56.             studentID: 5,  
  57.             studentName: 'Rahul',  
  58.             gender: 'Male',  
  59.             age: 26,  
  60.             course: 'MCA'  
  61.         }, ];  
  62.     }  
  63.     trackByStudentID(index: number, employee: any): string {  
  64.         return employee.studentID;  
  65.     }  
  66. }  

Let’s add trackBy function in student.component.html view file,

  1. <th>Odd Element</th>  
  2. </tr>  
  3. </thead>  
  4. <tbody>  
  5.     <tr *ngFor="let s of students;let i=index;let f=first;let l=last;let ev=even;let od=odd;trackBy:trackByStudentID">  
  6.         <td>{{i}}</td>  
  7.         <td>{{s.studentID}}</td>  
  8.         <td>{{s.studentName}}</td>  
  9.         <td>{{s.gender}}</td>  
  10.         <td>{{s.age}}</td>  
  11.         <td>{{s.course}}</td>  
  12.         <td>{{f}}</td>  
  13.         <td>{{l}}</td>  
  14.         <td>{{ev}}</td>  
  15.         <td>{{od}}</td>  
  16.     </tr>  
  17. </tbody>  
  18. </table> <br /> <button (click)='getStudents()'>Get More Students</button>  

Let’s look now at output and DOM elements in developer tools,

Angular

In the above example, on clicking "Get More Students" button, all the DOM elements are not affected, but only last one element has changed color of <tr> tag. That means Angular is now able to track all the items in the collection with the help of trackBy function.

Summary

This article described how to use ngFor local variables and trackBy function with ngFor directive; why we need trackBy function; and how Angular tracks all the elements with the help of trackBy function.

To learn Angular 2 ngFor Directive, click the below link, 

Write to me in comment box in case you need any help or you have any questions or concerns. Have a great day!