*ngFor for objects: how to get keys and values without losing performance

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

A problem familiar to every Angular developer

\n\n

Have you ever tried to display the contents of a regular JavaScript object in an Angular template using *ngFor and suddenly realized: "How do I get both the key and the value?" After all, *ngFor only works with arrays by default. And an object is not an array.

\n\n

This question is one of the most popular on Stack Overflow (thousands of views and dozens of answers). Developers are looking not just for a solution, but for the right solution — one that won't kill application performance, especially when the object is large or frequently updated.

\n\n

In this article, we won't just give an answer. We'll break down all the main approaches, from simple to advanced, and show you how to write code that is fast and stable. Let's go!

\n\n

Why doesn't *ngFor work with objects "out of the box"?

\n\n

The *ngFor directive in Angular is designed for iterable structures. An array is an iterable structure. An object is not. When you write:

\n\n
<div *ngFor="let item of myObject">{{ item }}</div>
\n\n

Angular will throw an error: "Cannot find a differ supporting object '...'". Angular simply doesn't know how to iterate over an object.

\n\n

But in practice, we often need to display data from an object: configs, dictionaries, API responses where keys have meaning (e.g., { name: 'Anna', age: 25, city: 'Moscow' }).

\n\n

The simplest way: Object.keys() and Object.entries()

\n\n

The most popular and obvious answer on Stack Overflow is to convert the object into an array directly in the template or in the component.

\n\n

Option 1: Object.keys() — get only keys

\n\n
// In the component (TypeScript)\nexport class MyComponent {\n  myObject = { name: 'Anna', age: 25, city: 'Moscow' };\n}
\n\n
<!-- In the template -->\n<div *ngFor="let key of objectKeys(myObject)">\n  Key: {{ key }}, Value: {{ myObject[key] }}\n</div>
\n\n

But there's a nuance here: objectKeys must be accessible in the template. Either make it a method of the component, or extract it into a separate property:

\n\n
// Component\nexport class MyComponent {\n  myObject = { name: 'Anna', age: 25, city: 'Moscow' };\n  objectKeys = Object.keys; // just a reference to the native function\n}
\n\n

This works, but it calls the function on every change detection cycle. If the object is large — this is a performance hit.

\n\n

Option 2: Object.entries() — keys and values at once

\n\n
// Component\nexport class MyComponent {\n  myObject = { name: 'Anna', age: 25, city: 'Moscow' };\n  get entries() {\n    return Object.entries(this.myObject);\n  }\n}
\n\n
<!-- Template -->\n<div *ngFor="let entry of entries">\n  Key: {{ entry[0] }}, Value: {{ entry[1] }}\n</div>
\n\n

Or with destructuring (more readable):

\n\n
<div *ngFor="let [key, value] of entries">\n  Key: {{ key }}, Value: {{ value }}\n</div>
\n\n

Pros: simple, clear, intuitive.
\nCons: the entries method will be called on every change detection cycle. For static objects — okay, for dynamic ones — it can become a problem.

\n\n

Performance: why is this important?

\n\n

Imagine your object contains 10,000 entries. Or it updates every 100 ms (e.g., real-time data from a server). Each call to Object.entries() creates a new array. Angular, on every change detection cycle, will see a "new" array and re-render the entire list. This leads to UI jitter, loss of focus on inputs, and slowdowns.

\n\n

Therefore, for serious projects, you need to use optim

Blogs

Book Recommendations