Angular *ngFor directive with an example

In this Angular ngFor Directive example article, we’ll see how to use angular’s ngFor directive.

ngFor is angular’s builtin structural directive which renders a template for each item of the supplied array.


Example

Now let’s see how to use it.


import { Component } from '@angular/core';
@Component({
  selector: 'app-demo',
  template: `<ul>     
        <li *ngfor="let product of products">{{ product.name }}</li>  
     </ul>`
})
export class AppComponent {
  products = [
    { name: "iPhone" },
    { name: "iPad" },
    { name: "MacBook Pro" },
    { name: "One Plus 6T" }
  ];
}

The output of the above code will look something like this inside HTML.

<ul>      
 <li>iPhone</li>      
 <li>iPad</li>      
 <li>Macbook Pro</li>      
 <li>One Plus 6T</li>
</ul>

How *ngFor works

Now let’s understand how the following code works.


<ul>      
 <li *ngfor="let product of products">{{ product.name }}</li> 
</ul>
  • products is the array that contains the list of product item.
  • of products means it will iterate over the products array.
  • let product creates the local variable named product which is having scope inside the li tag only where ngFor is defined.

*ngFor with local variables

You can use ngFor with the following exported variables

  • index : number: The index of the current 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.
  • 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.

  Now let’s see an example with each of the above variables.


*ngFor with index

In this example, we’ll see how to get index in Angular ngFor.


<ul>      
 <li *ngfor="let product of products;let i=index">
   {{i}}-{{ product.name }}
 </li> 
</ul>

The output of the above code will look like this:


<ul>      
 <li>0-iPhone</li>      
 <li>1-iPad</li>      
 <li>2-Macbook Pro</li>      
 <li>3-One Plus 6T</li>
</ul>

*ngFor with even and odd


<ul>      
  <li *ngfor="let product of products; let e=event; let o=odd" [class.odd]="o" [class.even]="e">
   {{ product.name }}
 </li>
</ul>

The output of the above code will look like this:


<ul>      
 <li class="even">iPhone</li>      
 <li class="odd">iPad</li>      
 <li class="even">Macbook Pro</li>      
 <li class="odd">One Plus 6T</li> 
</ul>

*ngFor with first and last

In this example, we’ll see how to apply class to first and last element in Angular ngFor directive.


<ul>      
 <li *ngfor="let product of products; let f=first; let l=last" [class.first]="f" [class.last]="l"> 
  {{ product.name }} 
 </li> 
</ul>

The output of the above code will look like this:


<ul>      
 <li class="first">iPhone</li>      
 <li>iPad</li>      
 <li>Macbook Pro</li>      
 <li class="last">One Plus 6T</li>  
</ul>

*ngFor with rxjs observable array

If we have products array as observable array then we can use it with ngFor as follows:
Here we are using async pipe with ngFor directive


<ul>      
   <li *ngfor="let product of (products$|async);"> 
       {{ product.name }}      
   </li>  
</ul>

The output of the above code will look like this:


<ul>      
  <li>iPhone</li>    
  <li>iPad</li>   
  <li>Macbook Pro</li>     
  <li>One Plus 6T</li> 
</ul>

*ngFor with trackBy

When the contents of the iterator changes, ngFor makes the corresponding changes to the DOM:

  • When an item is added, a new instance of the template is added to the DOM.
  • When an item is removed, its template instance is removed from the DOM.
  • When items are reordered, their respective templates are reordered in the DOM.

In this way, ngFor change propagation works.


Performance impact

This is fine for the small array, but if we have a huge list of the array, it definitely creates the performance issue.   Imagine if you have a large list of the array and if you are updating one of the items inside an array, Angular needs to remove all the DOM elements that associated with the data and create them again.    That means a lot of DOM manipulations and as we know, DOM manipulations are expensive;

The solution to the above problem is trackBy.

trackBy takes a function that has two arguments: index and item. If trackBy is given, Angular tracks changes by the return value of the function.

If a new item is added to the array or removed from the array or any update to the item then angular will keep track of that item using a supplied value of trackBy function.


import { Component } from '@angular/core';
@Component({
  selector: 'app-demo',
  template: `   
   <ul>    
      <li *ngfor="let product of products;trackBy: trackByFn">
      {{ product.name }}
      </li>   
  </ul>`
})
export class AppComponent {
  products = [
    { name: "iPhone" },
    { name: "iPad" },
    { name: "MacBook Pro" },
    { name: "One Plus 6T" }
  ];
  trackByFn(index, item) {
    return index;
  }
}

Here in the above code, we’ve defined to track the item by index.


I hope you like this Angular ngFor Directive example article!

Also Read: