Complete Guide to Iterating Object Key-Value Pairs Using *ngFor in Angular

Nov 02, 2025 · Programming · 28 views · 7.8

Keywords: Angular | *ngFor | Object Iteration | keyvalue Pipe | Performance Optimization

Abstract: This article provides a comprehensive exploration of various methods for iterating object key-value pairs in Angular using the *ngFor directive, with emphasis on the built-in keyvalue pipe introduced in Angular 6.1.0. It compares alternative implementations using Object.keys and custom pipes, offering complete code examples and performance optimization recommendations for developers at all levels.

Introduction

In modern web development, Angular's template directive system provides powerful tools for data manipulation, with *ngFor being one of the most commonly used iteration directives. However, when developers need to traverse key-value pairs of JavaScript objects, confusion often arises, particularly for those migrating from AngularJS to Angular 2+. This article systematically examines various approaches to object iteration in Angular.

Problem Context and Challenges

In AngularJS, developers could easily access object keys and values using the ng-repeat="(key, value) in demo" syntax. However, this syntax is no longer available in Angular 2+, creating a need for alternative solutions. The core issue stems from *ngFor being primarily designed for array iteration rather than object traversal.

Built-in Solution in Angular 6.1.0+: The keyvalue Pipe

Starting from Angular 6.1.0, the development team introduced the built-in keyvalue pipe specifically designed for iterating objects, Maps, and arrays. This pipe is available in the @angular/common module and offers straightforward implementation.

Basic usage example:

<div *ngFor="let item of testObject | keyvalue">
    Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</div>

In this example, the keyvalue pipe transforms the object into an array containing key and value properties, enabling proper iteration with *ngFor.

Advanced Usage for Maintaining Iteration Order

JavaScript object property order was unspecified prior to ES6. To maintain specific iteration sequences, the keyvalue pipe provides the keyvalue:onCompare parameter.

Comparison function implementation in component:

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

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html'
})
export class ExampleComponent {
  testObject = {
    'key1': [{'key11': 'value11'}, {'key12': 'value12'}],
    'key2': [{'key21': 'value21'}, {'key22': 'value22'}]
  };

  onCompare(_left: KeyValue<any, any>, _right: KeyValue<any, any>): number {
    return -1; // Custom sorting logic
  }
}

Template implementation:

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

Alternative Solutions for Angular 5 and Below

Using Object.keys Method

For earlier Angular versions, object iteration can be achieved by exposing the Object.keys method in the component.

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

@Component({
  selector: 'app-legacy-example',
  template: `
    <div *ngFor="let key of objectKeys(items)">
      {{key}}: {{items[key]}}
    </div>
  `
})
export class LegacyComponent {
  objectKeys = Object.keys;
  items = { 
    keyOne: 'value 1', 
    keyTwo: 'value 2', 
    keyThree: 'value 3' 
  };
}

Custom Pipe Approach

Another flexible solution involves creating custom pipes, offering better encapsulation and reusability.

Custom KeysPipe implementation:

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'keys'
})
export class KeysPipe implements PipeTransform {
  transform(value: any): any[] {
    if (!value) return [];
    
    return Object.keys(value).map(key => ({
      key: key,
      value: value[key]
    }));
  }
}

Pipe registration in module:

import { NgModule } from '@angular/core';
import { KeysPipe } from './keys.pipe';

@NgModule({
  declarations: [KeysPipe],
  exports: [KeysPipe]
})
export class SharedModule { }

Template usage:

<div *ngFor="let entry of demo | keys">
  Key: {{entry.key}}, Value: {{entry.value}}
</div>

Performance Optimization and Best Practices

Using trackBy for Performance Enhancement

When handling large objects or frequently updated data, using the trackBy function can significantly improve rendering performance.

<div *ngFor="let item of object | keyvalue; trackBy: trackByKey">
  {{item.key}}: {{item.value}}
</div>

trackBy implementation in component:

trackByKey(index: number, item: any): string {
  return item.key; // Use key as unique identifier
}

Handling Nested Objects

For complex data structures containing nested objects, combined approaches can be employed:

<div *ngFor="let outerItem of nestedObject | keyvalue">
  <h3>{{outerItem.key}}</h3>
  <div *ngFor="let innerItem of outerItem.value">
    <span *ngFor="let prop of innerItem | keyvalue">
      {{prop.key}}: {{prop.value}}
    </span>
  </div>
</div>

Version Compatibility Considerations

When selecting a solution, consider the project's Angular version:

Practical Application Scenarios

These techniques find wide application in real-world development:

Conclusion

Angular provides multiple flexible approaches for handling object key-value pair iteration requirements. Starting from Angular 6.1.0, the built-in keyvalue pipe represents the most recommended standard solution, offering excellent type support and performance optimization. For earlier versions, both Object.keys method and custom pipes serve as viable alternatives. Developers should choose the most appropriate implementation based on specific project requirements, Angular version, and performance considerations.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.