A problem familiar to every Angular developer
\n\nHave 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.
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\nIn 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\nWhy doesn't *ngFor work with objects "out of the box"?
\n\nThe *ngFor directive in Angular is designed for iterable structures. An array is an iterable structure. An object is not. When you write:
<div *ngFor="let item of myObject">{{ item }}</div>\n\nAngular will throw an error: "Cannot find a differ supporting object '...'". Angular simply doesn't know how to iterate over an object.
\n\nBut 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' }).
The simplest way: Object.keys() and Object.entries()
\n\nThe 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\nOption 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\nBut 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:
// 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\nThis works, but it calls the function on every change detection cycle. If the object is large — this is a performance hit.
\n\nOption 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\nOr with destructuring (more readable):
\n\n<div *ngFor="let [key, value] of entries">\n Key: {{ key }}, Value: {{ value }}\n</div>\n\nPros: 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.
Performance: why is this important?
\n\nImagine 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.
Therefore, for serious projects, you need to use optim