Author avatar

Gaurav Singhal

Repeating Data with ngFor

Gaurav Singhal

  • Apr 25, 2020
  • 5 Min read
  • 608 Views
  • Apr 25, 2020
  • 5 Min read
  • 608 Views
Languages Frameworks and Tools
Front End Web Developer
Client-side Frameworks
Angular

Introduction

*ngFor is a predefined directive in Angular. It accepts an array to iterate data over atemplate to replicate the template with different data. It's the same as the forEach() method in JavaScript, which also iterates over an array.

A Real-life Example

There are a lot of places where you can use the *ngFor directive.

A clear example to illustrate the need for *ngFor is the HTML5 <select> tag, which has a lot of <option> tags with different values and labels.

1
2
3
4
5
6
<select>
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  <option value="4">4</option>
</select>
html

Here, you have multiple option elements in a select tag where the same template is iterating with change in label and value.

In the HTML5 table element, you have the same number of columns in all rows but with different values.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<table>
  <thead>
    <tr>
      <td>First Name</td>
      <td>Last Name</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>John</td>
      <td>Doe</td>
    </tr>
    <tr>
      <td>Jane</td>
      <td>Doe</td>
    </tr>
    <tr>
      <td>Betty</td>
      <td>Miller</td>
    </tr>
  </tbody>
</table>
html

In the following section, you'll see how to implement the above templates using the *ngFor directive.

Implementing ngFor

*ngFor accepts an array to iterate the data over a HTML template.

Begin by creating a local variable for an array consisting of string values.

app.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent {
  options: string[];

  constructor() {
    this.options = [
      "option1",
      "option2",
      "option3",
      "option4",
      "option5",
      "option6"
    ];
  }
}
ts

Define the options variable in app.component.ts and in the constructor, and initialize options with dummy values.

app.component.html

1
2
3
<select>
  <option [value]="option" *ngFor="let option of options">{{option}}</option>
</select>
html

Some points to note about the option element.

First, the *ngFor directive is used to iterate over the values of the options array. It's like a forEach loop where a single value is considered, putting it in the value attribute of an option element. Interpolation ({{}}) is used to print the label in the option elements.

Second, the value attributes are included inside the square brackets ([]) to get dynamic values. The value of the option variable changes according to the iteration.

After running the application, you'll see the output as shown below.

imagur

You don't have to write the option element six times. The *ngFor directive does it for you. If you inspect the select element in the browser, you can see the following.

imagur

You can also get the index of the element using the *ngFor directive, similar to the forEach() loop in JavaScript. All you have to do is add a new variable in the *ngFor directive.

app.component.html

1
2
3
4
5
<select>
  <option [value]="option" *ngFor="let option of options;let i=index;"
    >{{i+1}}.{{option}}</option
  >
</select>
html

In the above snippet, a new variable, i, is added to get the index. You can also write it another way, as shown below.

app.component.html

1
2
3
4
5
<select>
  <option [value]="option" *ngFor="let option of options;index as i"
    >{{i+1}}.{{option}}</option
  >
</select>
html

You can improve the performance of *ngFor by adding the trackBy variable.

trackBy accepts a function taht returns a unique identifier. It will track overall values and re-render the portion that is modified and requires changes.

app.component.html

1
2
3
4
5
6
7
<select>
  <option
    [value]="option"
    *ngFor="let option of options;let i=index;trackBy:trackByOption"
    >{{i+1}}.{{option}}</option
  >
</select>
html

Now, write a function in app.component.ts.

app.component.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.scss"]
})
export class AppComponent {
  options: string[];

  constructor() {
    this.options = [
      "option1",
      "option2",
      "option3",
      "option4",
      "option5",
      "option6"
    ];
  }

  trackByOption(index, option) {
    return option;
  }
}
ts

Run the application to check these changes. You can see the output below.

imagur

Conclusion

This guide discussed the *ngFor directive with a simple example to help you understand it. You will come across many scenarios where you will notice the exact use of index and trackBy. Apart from index and trackBy, there are multiple exported values in the *ngFor directive, such as event, odd, first, and last. You can use these exported values to make your UI beautiful and performant. You just need to make an alias of these exported values, and they are ready to be used.

Read and explore more about it here.

4