ngFor In Angular

ngFor In Angular

In this article, we will learn about the syntax and how to use ngFor to display a list of movies using example code. The ngFor directive in Angular iterates over a collection of data, such as an array or a list, and constructs an HTML element for each item using an HTML template. It allows us to create lists or tables to present tabular data in a visually appealing manner. The ngFor also outputs a number of local variables, including Index, First, Last, Odd, Even, and Trackby, among others. 

Syntax of ngFor

The syntax for the ngFor command is as follows.

<html-element ngFor="let <item> of <items>;”> 
     <html-Template></html-Template>
</html-element>


<html-element>:

is the element to which the ngFor directive is applied. For each item in the collection, it repeats the <html-element>...</html-element>.

*ngFor :

*ngFor is the first character in the syntax. ngFor is an Angular structural directive, as indicated by the *.

let <item> of <items>;

The Template input variable is item. It represents the item from the <items> that is now being iterated. <items> is a collection that has to be displayed to the user. It's usually a property on your component class that you may iterate over. (This is usually an array.)

The item's scope is contained within the <html-element>..</html-element> tag. Within it, you can access it from anywhere, but not outside of it.

ngFor Example

Let's look at an example of how to use ngFor.

Now, Create a new Angular Application. If you're new to Angular, start with Angular and create a new project tutorial. Our application is styled with Bootstrap 4. As a result, you can add the following to index.html.
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">

A list of the top ten movies is included in the code. Let's use ngFor to create a template for displaying the movies.

Now, Open the app.component.ts and add the following code:
import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  title: string ="Top 5 Movies" ;
 
 
  movies: Movie[] =[
 
  {title:'Zootopia',director:'Byron Howard, Rich Moore',cast:'Idris Elba, Ginnifer Goodwin, Jason Bateman',releaseDate:'March 4, 2016'},
  {title:'Batman v Superman: Dawn of Justice',director:'Zack Snyder',cast:'Ben Affleck, Henry Cavill, Amy Adams',releaseDate:'March 25, 2016'},
  {title:'Captain American: Civil War',director:'Anthony Russo, Joe Russo',cast:'Scarlett Johansson, Elizabeth Olsen, Chris Evans',releaseDate:'May 6, 2016'},
  {title:'X-Men: Apocalypse',director:'Bryan Singer',cast:'Jennifer Lawrence, Olivia Munn, Oscar Isaac',releaseDate:'May 27, 2016'},
  {title:'Warcraft',director:'Duncan Jones',cast:'Travis Fimmel, Robert Kazinsky, Ben Foster',releaseDate:'June 10, 2016'},
]
 
 
}
 
class Movie {
  title : string;
  director : string;
  cast : string;
  releaseDate : string;
}

Use of ngFor

To make use of ngFor, follow these steps.

  1. Make a block of HTML components that can be used to show a single movie.
  2. To repeat the block for each movie in the movies, use the ngFor command.

Now, Open the app.component.html and add the following code:
<h1> {{title}} </h1>
 
  <ul>
    <li *ngFor="let movie of movies">
      {{ movie.title }} - {{movie.director}}
    </li>
  </ul>

The movies are displayed using the ul. A single movie is displayed in the li element. For each movie, we must repeat the li. As a result, we use ngFor on the li element.

The let movie of movies method iterates over the movies collection, which is a component class attribute. the movie is a Template input variable that represents the iterated movie from the collection at the moment. The movie title and director's name are displayed via Angular Interpolation.

Now run the application using the following command
ng serve

See the output looks like below

Angular ngFor Example

Similarly, as demonstrated below, you can use the table element to display the movies. For each movie, we must repeat the tr element. As a result, use the tr directive.

Open the app.component.html and add the following code:
<div class='panel panel-primary'>
    <div class='panel-heading'>
        {{title}}
    </div>
 
    <div class='panel-body'>
        <div class='table-responsive'>
            <table class='table'>
                <thead>
                    <tr>
                        <th>Title</th>
                        <th>Director</th>
                        <th>Cast</th>
                        <th>Release Date</th>
                    </tr>
                </thead>
                <tbody>
                    <tr *ngFor="let movie of movies;">
                        <td>{{movie.title}}</td>
                        <td>{{movie.director}}</td>
                        <td>{{movie.cast}}</td>
                        <td>{{movie.releaseDate}}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</div>

Now, run the application using the ng serve command

See the output looks like below

Angular ngFor Example


Nested Array

The example below demonstrates how to use the ngFor in a nested array. There are hierarchical skills arrays in the employee's array.
 employees = [
    {
      name: "Rahul", email: "rahul@gmail.com",
      skills: [{ skill: 'Angular', exp: '2' },{ skill: 'Javascript', exp: '7' },{ skill: 'TypeScript', exp: '3' }
      ]
    },
    {
      name: "Sachin", email: "sachin@gmail.com",
      skills: [{ skill: 'Angular', exp: '1' },{ skill: 'Android', exp: '3' },{ skill: 'React', exp: '2' }
      ]
    },
    {
      name: "Laxmna", email: "laxman@gmail.com",
      skills: [{ skill: 'HTML', exp: '2' },{ skill: 'CSS', exp: '2' },{ skill: 'Javascript', exp: '1' }
      ]
    }
  ]

Use the local variable employee to acquire the list of skills and loop through it using *ngFor="let skill of employee skills;" inside the main loop.
<div class='card'>
  <div class='card-header'>
    <p>Nested Array</p>
  </div>
 
  <div class='table-responsive'>
    <table class='table table-bordered table-sm '>
      <thead class="thead-dark">
        <tr>
          <th>Name</th>
          <th>Mail ID</th>
          <th>Skills</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let employee of employees;">
          <td>{{employee.name}}</td>
          <td>{{employee.email}}</td>
          <td>
            <table class='table table-sm '>
              <tbody>
                <tr *ngFor="let skill of employee.skills;">
                  <td>{{skill.skill}}</td>
                  <td>{{skill.exp}}</td>
                </tr>
              </tbody>
            </table>
 
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Local Variables

ngFor offers a number of values that can be used to fine-tune the presentation. These values are assigned to the local variable, which we then use in our template.

The ngFor directive provides a list of exported values.

  • index: number: The current element's zero-based index in the collection.
  • count: number: The collection's total number of items
  • first: boolean: When the item is the first in the collection, this is True.
  • last: boolean: When the item is the final in the collection, it is set to True.
  • even: boolean: True if the item in the collection has an even index.
  • odd: boolean: When an item in the collection has an odd index, it is set to True.

Finding the Index

To find the index, we create a new local variable I and set it equal to the index using the let operator.

let i=index;

The following code displays a list of movies as well as an index.
<tr *ngFor="let movie of movies; let i=index;">
    <td> {{i}} </td>
    <td>{{movie.title}}</td>
    <td>{{movie.director}}</td>
    <td>{{movie.cast}}</td>
    <td>{{movie.releaseDate}}</td>
</tr>

Formatting odd & even rows

The odd and even values can be used to format the odd and even rows, respectively. Create two local variables, oe, to do this. Using the let statement, assign the values of odd and even values to these variables. Then update the class name to odd or even using the ngClass. The following is an example of code.
<tr *ngFor="let movie of movies; let i=index; let o= odd; let e=even;" [ngClass]="{ odd: o, even: e }">
    <td> {{i}} </td>
    <td>{{movie.title}}</td>
    <td>{{movie.director}}</td>
    <td>{{movie.cast}}</td>
    <td>{{movie.releaseDate}}</td>
</tr>

In app.component.css, add the proper background color to the odd and even classes, as shown below.
.even { background-color: azure; }
.odd { background-color: floralwhite; }

The first and the Last element of a list

Similarly, the first and last values can be used to style the first and last elements. Using the ngClass, the code below will add CSS classes first and last to the first and last movies.
<div class='table-responsive'>
  <table class='table table-bordered table-sm '>
    <thead class="thead-dark">
      <tr>
        <th>Index</th>
        <th>Title</th>
        <th>Director</th>
        <th>Cast</th>
        <th>Release Date</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let movie of movies; let i=index; let first= first; let last=last;" [ngClass]="{ first: first, last: last }">
        <td> {{i}} </td>
        <td>{{movie.title}}</td>
        <td>{{movie.director}}</td>
        <td>{{movie.cast}}</td>
        <td>{{movie.releaseDate}}</td>
      </tr>
    </tbody>
  </table>
</div>

Don't forget to include the CSS classes in app.component.css.
.first { background-color: azure; }
.last { background-color: floralwhite; }

Track By

In the same way, as AngularJS does, angular adds a Track By clause. You can use the Track By clause to identify items using your own key.

When comparing elements in a collection to DOM nodes, Angular uses the object identity. As a result, when you add or remove elements from the DOM, Angular will keep track of them and only update the objects that have changed. The complete list isn't displayed.

If the list is updated from the backend server, however, this will fail. Because the reference has changed, the retrieved items cannot be compared to the list's existing objects. Angular simply remove these items from the DOM and replaces them with fresh data. This will have a significant impact on performance.

By informing Angular how to find related items, the trackBy clause solves this problem. Angular will match the elements given by the database using the value returned by the trackBy method and update the DOM Elements without having to recreate them.

As the trackBy clause, we should always use the primary key or unique key.

Example

Let's use the movie title as the identification in our movie list example.
<tr *ngFor="let movie of movies; trackBy:trackByFn;">
    <td>{{movie.title}}</td>
    <td>{{movie.director}}</td>
    <td>{{movie.cast}}</td>
    <td>{{movie.releaseDate}}</td>
</tr>

Create a trackByFn in the Component Class. Its arguments are the index and the current item. It should return the one-of-a-kind id.
trackByFn(index, item) {
    return item.title;
  }

Conclusion

In this article, we learned about ngFor syntax and how to use ngFor to display a list of movies with example.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in comment section.

Post a Comment

Previous Post Next Post