Looping through a static array of objects using *ngFor results in continuous DOM updates

My issue involves a basic component that iterates over a static array of objects, displaying the content. Once this component is integrated into the larger application, the content appears correctly, but I am unable to register any click events on it. Upon inspecting the element in Chrome by right-clicking and selecting "Inspect," the hierarchy only displays the body tag and does not drill down to the individual element as expected.

Upon manual inspection, it seems that the component is constantly being updated by the DOM (with the div tag flashing). This is puzzling as there should be no changes detected since it is a static array.

Interestingly, when I change the object array to a simple string array ['a', 'b', 'c'], everything works as expected and the DOM stops updating.

The additional elements added to the template outside of the ngFor loop remain unaffected and do not experience constant updates.

I am currently using version 2.4.1

Simplified Component

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

@Component({
selector: 'app-ngfor-test',
templateUrl: './ngfor-test.component.html',
styleUrls: ['./ngfor-test.component.css']
})
export class NgforTestComponent {

get items() {
return [
{
'label': 'a',
'value': 'first'
},
{
'label': 'b',
'value': 'second'
},
{
'label': 'c',
'value': 'third'
}
];
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Template

<div class="item-container" *ngFor="let item of items">
<label>{{ item.label | uppercase }}</label>
<span>{{ item.value }}</span>
</div>

Answer №1

In reference to @seidme's point, the getter function gets called every time change detection is triggered, which can occur frequently.

get items() {
    return [
        {
            'label': 'a',
            'value': 'first'
        },
        {
            'label': 'b',
            'value': 'second'
        },
        {
            'label': 'c',
            'value': 'third'
        }
    ];
}

Each call to this function creates a new object instance, causing ngFor to re-render the list.

If you modify it to

items = [
        {
            'label': 'a',
            'value': 'first'
        },
        {
            'label': 'b',
            'value': 'second'
        },
        {
            'label': 'c',
            'value': 'third'
        }
    ];

get items() {
  return this.items;
}

it will prevent unnecessary re-rendering, as Angular recognizes that it has received the same object instance and no changes have occurred requiring an update or re-render.

Answer №2

When you use a getter with the *ngFor directive, it binds an object property to a function that gets called every time Angular runs change detection. In this situation, the getter always returns a new array object which causes reference changes and forces Angular to re-render the list.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Card collapse upon being clicked

I am encountering an issue with a collapsed card in Angular. Here is the code for my component: @Component({ selector: 'app-numbered-card', templateUrl: './numbered-card.component.html', styleUrls: ['./numbered-card.component ...

Tips for adjusting the dimensions of images in the primeng editor

Currently working on an Angular 8 application that utilizes the prime ng editor. I am looking to set limits for image size and dimensions before uploading via the upload image button, but encountering difficulties in implementing this feature. https://i.s ...

Guide on how to import or merge JavaScript files depending on their references

As I work on my MVC 6 app, I am exploring a new approach to replacing the older js/css bundling & minification system. My goal is to generate a single javascript file that can be easily referenced in my HTML. However, this javascript file needs to be speci ...

Eslint requires that return values are used effectively

I am seeking a TypeScript or ESLint rule that enforces the usage of return values from functions. For example: const getNum = () => 12 This rule should allow me to call the function and store the returned value like this: const a = getNum() However, i ...

Properly incorporating life cycle hooks into an abstract base component in Angular: A comprehensive guide

I have a unique abstract base component that includes life cycle hooks: export abstract class BaseComponent implements OnChanges, OnInit { ngOnChanges(changes: SimpleChanges): void { … } ngOnInit() { … } } Now, let's discuss a ...

TypeScript introduces a flexible generic type, Optional<T, Props>, allowing customized props for a specific

In my attempt to develop a type called Optional<T, TProps>, where T represents the initial type and TProps is a union type of properties that need to be optional. As an illustration: type A = Optional<{a: string, b: string}, 'a'&g ...

Spring MVC seems to be ignoring the static resources specified in the HTML files

Currently, I am in the process of creating a straightforward Spring MVC (v4.1.2) and Angular4 application. Essentially, this application performs CRUD operations by sending HTTP requests from the Angular client. The following combination works seamlessly ...

Angular 2 Date Input failing to bind to date input value

Having an issue with setting up a form as the Date input in my HTML is not binding to the object's date value, even though I am using [(ngModel)] Here is the HTML code snippet: <input type='date' #myDate [(ngModel)]='demoUser.date& ...

Why does Angular throw a length-related error, while I am able to retrieve the length using console log if needed?

It appears that Angular is not receiving the correct data type it expects, yet the lack of errors in the terminal is puzzling. However, the console output states: https://i.stack.imgur.com/1xPsg.jpg If the length property can be detected (highlighted in ...

When attempting to instantiate a list from JSON in Angular, the type '{}' is lacking the following properties compared to type 'Datos[]'

I'm encountering issues when trying to incorporate JSON data into my Angular application. My Process: Importing the JSON file into a variable: import _data from '../../../assets/data.json'; Following the advice from responses in this t ...

Obtain the type parameter in Typescript

In my code, I have created a simple IFactory<OUT> interface along with two classes that implement it. export interface IFactory<OUT = any> { create(): OUT; } // number implementation export class NumberFactory implements IFactory<number ...

Establish a spacing between a pair of geometries in THREE.JS

I need assistance with adjusting the distance between cylinders and sprites generated by this code. What steps can I take to achieve this? const THREE = this.context.three; const textureLoader = new THREE.TextureLoader(); const geometr ...

Implementing grid items in CSS Grid that do not stretch the grid row and have a container that is scrollable

Here is my dilemma: I am looking to create a grid with a fixed number of columns (that can be adjusted via javascript) and a variable number of rows, all with equal heights. The rows will be determined by the number of grid items, which are represented a ...

sending information to ng-content from mother in Angular

In the container-page.component.ts, I have set up the following structure using the ngrx approach. <parent-comp><child-comp [someInput]="someValue"></child-comp></parent-comp> Within the template of parent-comp, there is: <div ...

Receiving a response of success or failure when using android.SmsManager.sendTextMessage() in a NativeScript/Android application

I have a question regarding sending an SMS from my NativeScript mobile application. Below is the code I am using: sendSms(numbers, body) { let sms = android.telephony.SmsManager.getDefault(); sms.sendTextMessage(numbers, null, body, null, ...

After destructuring, useParams may sometimes return as undefined

I'm encountering an issue with undefined variables being returned even after destructuring when using useParams(). I've tried various solutions but none seem to work for me. const App = () => { return ( <div className="container"> ...

What is the best way to check the API response status in NextJS13?

Currently, I am experimenting with different methods to handle API HTTP status in my NextJS-13 project but so far nothing has been successful. Note: TypeScript is being used in this project. Below is my code snippet with a static 200 API response and the ...

Changing data types conditionally in Angular using TypeScript

My angular component relies on the API Response for its functionality. I receive these responses from an external API. When there are no errors Data : { Status: string; Data: number; } When an error occurs, this is what I get. Data : { Status: string; ...

Angular 14: Removing elements from FormArray causes the remaining elements to lose their values

My form includes custom inputs and utilizes the ControlValueAccessor. To view the implementation, visit this link. I encountered an issue where deleting an item from a FormArray would inadvertently clear the values of the other FormGroups still present in ...

Angular: Design dependent on attributes

Can I customize the styling of a div in accordance with a boolean property called "isActive" on my controller using Angular? <div class="col-md-3" (click)="isActive = !isActive"> <div class="center"> <i class="fa fa-calendar"& ...