Beginners Guide To Angular ngFor (With Code Examples)

Luis Ramirez Jr
Luis Ramirez Jr
hero image

If you're a budding Angular developer, you've probably come across ngFor, one of Angular's built-in directives that can turn your complex tasks into a walk in the park.

Not only can it streamline your application's flow and make your coding journey significantly smoother, but thanks to its ability to let you loop through items in an array directly within your templates, it can help keep your code clean, concise, and easy to read.

But how do we use it?

Well, good news! In this beginner tutorial, we'll take a deep dive into Angular's ngFor directive and I'll teach you how it works.

Everything from its fundamental mechanics and applications to common errors and their solutions. So whether you're looking to stripe a table, find the index of a list element, or loop through static numbers and objects, I've got you covered.

And we won't stop there. We'll also take a look at how ngFor behaves during dynamic list modifications and delve into more complex tasks, such as nesting ngFor to display objects within objects.

Armed with this knowledge, you'll not only ace your Angular development projects, but you'll save hours of debugging time by avoiding common pitfalls.

You can think of this guide as your one-stop solution to mastering ngFor in Angular!

Let’s get started.

What is ngFor in Angular?

ngFor is a powerful built-in directive in Angular that simplifies the process of rendering dynamic lists within your HTML templates.

It lets you loop through items in an array, creating a new HTML element for each item according to the template you define. This not only makes your code cleaner and more concise but also enhances its maintainability by reducing redundancy.

How does ngFor work?

The ngFor directive operates by duplicating a block of HTML for each item in an array. You use the let item of items syntax to instruct Angular to create a new instance of the block for every item in your collection.

For example

  <li *ngFor="let item of items">{{item}}</li>

In this code snippet, ngFor is applied to a <li> element, generating a new list item for each item in the items array. While the * symbol before ngFor signifies a shorthand that Angular uses to expand this into a more complex HTML structure behind the scenes, allowing you to maintain a clean and readable template.

This directive is not limited to simple data types; it can efficiently handle arrays of complex objects. For instance, consider an array of users, where each user has a name and an email.

For example

Let's say I have an array of users, where each user is an object with properties name and email. Here's how I might use ngFor to display this data:

  <li *ngFor="let user of users">
    {{user.name}} ({{user.email}})
  </li>

Each user’s name and email are displayed in separate list items, demonstrating ngFor’s capability to iterate over data structures and embed dynamic content within HTML effortlessly.

Mastering ngFor allows you to dynamically generate content tailored to the needs of your application, significantly reducing code redundancy and enhancing the flexibility and readability of your Angular templates.

By understanding the basics and leveraging the directive's full potential, you can efficiently manage dynamic lists and complex data structures, paving the way for more advanced Angular development techniques.

What can we do with ngFor in Angular?

Alright, let's look at some applications for this directive.

We’ve talked about a few options already but we’ve added them again below along with other features, so you can have all of these in one place.

Looping over an Array

One of the basic uses of ngFor is to iterate over an array. Imagine I have an array of names and we want to display each one in a list.

Using ngFor, I can do this with minimal coding.

let names = ['John', 'Jane', 'Amy', 'Emma'];

<div *ngFor="let name of names">
  {{name}}
</div>

In this example, ngFor loops over the names array and assigns each value to the variable name which is then displayed in the div.

Looping over an Array of Objects

Arrays in real-world applications often contain objects, and ngFor can handle this too.

For example

Let's say I have an array of user objects, where each object has properties like id and username:

let users = [{id: 1, username: 'john'}, {id: 2, username: 'jane'}];

<div *ngFor="let user of users">
  ID: {{user.id}}, Name: {{user.username}}
</div>

Here, ngFor loops over each user object in the user's array. It then accesses the id and username properties of each user object and displays them.

Looping over an Array with Index

Sometimes, we need to display the index of each item along with its value. With ngFor, I can easily get the index of the current item in the loop like so:

let colors = ['Red', 'Green', 'Blue'];

<div *ngFor="let color of colors; let i = index">
  {{i+1}}. {{color}}
</div>

The i=index part of the code assigns the current index to i which can then be used in the template.

How to stripe a table using even and odd

Stripping a table can improve readability by visually separating each row, and ngFor offers the even and odd variables to make this option nice and straightforward:

let items = ['Item1', 'Item2', 'Item3', 'Item4'];

<tr *ngFor="let item of items; let i = index; let e = even" [class.even-row]="e">
  <td>{{i+1}}</td><td>{{item}}</td>
</tr>

Here, I use ngFor in combination with Angular's class binding syntax. When the row is even (even-row), I apply a different CSS class, which could, for example, change the row's background color.

Identifying the first and last elements in a list

When dealing with collections, it's not uncommon to require special handling for the first and last items, but with ngFor, you can easily identify the first and last elements in your iteration:

let teams = ['Team1', 'Team2', 'Team3'];

<div *ngFor="let team of teams; let isFirst = first; let isLast = last">
  <p>{{team}} - First: {{isFirst}} - Last: {{isLast}}</p>
</div>

isFirst and isLast variables directly give you Boolean values indicating whether the current item is the first or last in the array.

Adding or removing items from the list

Your lists won't always be static, and you might need to add or remove items. Here's how ngFor handles dynamic list modifications:

let fruits = ['Apple', 'Banana', 'Cherry'];

// Adding an element
fruits.push('Orange');

// Removing an element
let index = fruits.indexOf('Cherry');
if (index !== -1) {
  fruits.splice(index, 1);
}

<div *ngFor="let fruit of fruits">
  {{fruit}}
</div>

As soon as the fruits array changes, ngFor updates the DOM to match. This makes managing dynamic lists simple and efficient.

Looping over static numbers

ngFor can also be used to generate a loop of static numbers, which is useful for cases where you want to display a certain number of elements or create pagination:

<div *ngFor="let number of '.repeat(5).split(','); let i = index">
  {{i+1}}
</div>

In this example, this code will display numbers from 1 to 5.

Looping over objects

ngFor isn't just for arrays. It can also loop over the properties of an object:

let user = {id: 1, name: 'John', age: 30};

<div *ngFor="let item of user | keyvalue">
  {{item.key}}: {{item.value}}
</div>

Notice the keyvalue pipe here, as this transforms our object into an array of key-value pairs that ngFor can loop over.

Using nested ngFor

Finally, ngFor can also support nesting - like a loop within a loop. This is useful for dealing with complex data structures:

let users = [
  {
	name: 'John',
	skills: ['Java', 'Angular', 'Python']
  },
  {
	name: 'Jane',
	skills: ['C#', 'React', 'Node']
  }
];

<div *ngFor="let user of users">
  {{user.name}}
  <ul>
	<li *ngFor="let skill of user.skills">
  	{{skill}}
	</li>
  </ul>
</div>

This code will loop over each user, and then loop over each of their skills, displaying them in a nested list.

Phew! So that was a quick whirlwind tour of the various applications of Angular's ngFor directive, from simple loops to dynamic list management, and from indexing to nested looping.

With a grasp of these concepts, you'll have a powerful toolset for front-end development at your disposal.

Common ngFor errors to watch out for

Even with a solid understanding of ngFor, you might encounter occasional errors, which is ok. It's an essential part of the development and learning process!

To help you save some time and figure out what went wrong, here are some common ngFor- related errors and their solutions:

Using 'in' instead of 'of'

This is a common mistake made by JavaScript developers transitioning to Angular, as they often use 'in' for looping in JavaScript.

But in the ngFor directive, we use 'of', and so using 'in' would throw an error in Angular.

// Incorrect
<div *ngFor="let item in items">
  {{item}}
</div>

// Correct
<div *ngFor="let item of items">
  {{item}}
</div>

Using a non-iterable object in ngFor

ngFor can't iterate through non-iterable objects. If you attempt to do so, Angular throws an error.

let nonIterableObject = 10;

// Throws error: Cannot find a different supporting object '10' of type 'number'
<div *ngFor="let number of nonIterableObject">
  {{number}}
</div>

In this example, I try to iterate over a number, which is non-iterable, so make sure to use only iterable objects, like arrays or strings, with ngFor.

Directly modifying the index

Modifying the index variable in ngFor is a bad practice and could lead to unexpected results.

This is because Angular's ngFor uses the index only for read operations, and making changes to it won't affect the original array.

// Incorrect and ineffective
<div *ngFor="let item of items; let i = index">
  {{i++}}. {{item}}
</div>

Cannot read property 'property name' of undefined

This error occurs if we try to access a property of an undefined object in our array during looping.

let users = [{name: 'John'}, {name: 'Jane'}, null, {name: 'Emma'}];

// Throws error: Cannot read property 'name' of null
<div *ngFor="let user of users">
  {{user.name}}
</div>

Ensure each object in your array is defined and has the properties you're trying to access.

TL;DR

This isn't an exhaustive list of ngFor errors. Just remember that debugging is a part of the development process. Each error message gives you a direction to find the problem in your code. So, consider them your guides, not your enemies!

How does ngFor keep track of items?

Angular uses a strategy called trackBy to keep track of each element in an array when using the ngFor directive, especially when the array is updated by adding or removing elements.

This is particularly important for performance optimization and to maintain the state of DOM elements, such as input focus or component states.

Why?

Well, when you use ngFor without a trackBy function, Angular tracks elements using object identity. This means that every time the array changes, Angular performs a DOM manipulation by removing elements and reinserting them, even if the actual object references haven’t changed.

This can lead to performance issues and unwanted behavior (like losing focus on an input element).

Truthfully, rendering lists is never as simple as just using the ngFor directive.

There are a lot of optimizations you may need to take to render a list. From my experience, one of the best ways to optimize performance and avoid unnecessary DOM updates is by providing a trackBy function.

This function then tells Angular how to identify a unique identifier for each item. If the unique identifier hasn't changed, Angular will keep the corresponding DOM element intact.

Let’s look at an example.

How to define a trackBy function

You need to define a function in your component that takes two arguments:

  1. the index of the item in the iterable
  2. and the actual item itself.

The function should return a unique identifier for each item, like so:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <ul>
      <li *ngFor="let item of items; trackBy: trackById">
        {{ item.id }} - {{ item.name }}
      </li>
    </ul>
    <button (click)="addItem()">Add Item</button>
  `
})
export class AppComponent {
  items = [
    { id: 1, name: 'Item 1' },
    { id: 2, name: 'Item 2' }
  ];

  trackById(index: number, item: any): number {
    return item.id; // Use unique identifier as a tracking function
  }

  addItem() {
    this.items.push({ id: this.items.length + 1, name: `Item ${this.items.length + 1}` });
  }
}

So what's happening here?

Well, in this example:

  • The trackById function returns the id property of each item. Since the id is unique for each item, Angular uses it to track the item's identity across updates
  • When items are added or the order changes, Angular only makes DOM updates for the actual changes instead of re-rendering the entire list, improving performance and maintaining state-like input focus

Why use trackBy?

  • It minimizes the number of DOM manipulations, improving the performance of your application
  • It maintains the state of existing elements, such as input fields and component lifecycle states, when the array changes
  • Only items that have changed are re-rendered or added/removed from the DOM, which is more efficient than rebuilding the entire list

So what are you waiting for? Try out `ngFor` with your projects today!

Hopefully, this guide has shined a light on how and when to use this directive.

The ability to manage and manipulate collections of data effectively is paramount, and this is where ngFor shines, but remember to also add in trackBy to help run it even smoother.

All that’s left now is for you to try this out in your own code. It might seem simple, but mastering ngFor and Angular as a whole can open up a world of opportunities.

Employers are always on the lookout for developers who can build efficient, scalable web applications, and Angular is often their framework of choice. So keep learning, keep coding, and who knows where your skills will take you next!

P.S.

If you want to learn more about this directive, and want a deeper understanding of Angular, then check out my complete Angular Bootcamp course.

learn angular

I guarantee it's the only course you need to learn Angular, build enterprise-level applications from scratch (including a massive video sharing application), and be able to get hired as an Angular Developer this year.

Even better? When you join, you’ll also get access to me and 1,000s of other students, and working developers, inside the ZTM Discord.

Ask questions, help others, or just network with other devs and other tech professionals.

With a 30 day money back guarantee, you’ve got nothing to lose.

Happy coding!

More from Zero To Mastery

Angular vs React vs Vue: The Best Framework for 2024 is… preview
Angular vs React vs Vue: The Best Framework for 2024 is…

We are going to look at job postings, developer statistics, download numbers, and other factors, to actually burst through the fuzzy cloud that is React, Angular and Vue to help you decide what you should learn for your career.

Getting Started With Animations For Angular: Fade + FadeSlide preview
Getting Started With Animations For Angular: Fade + FadeSlide

Do you want to improve the user experience for your angular app? Learn how to set up simple animations today!

Top 25 Essential Angular Interview Questions + Answers preview
Top 25 Essential Angular Interview Questions + Answers

❌ Don't try to learn 100+ questions! These are the CORE 25 angular interview questions that if you can understand and answer - you'll ace anything they ask.