Reputation: 967
I have data to be rendered in the table. Let's consider these 5 rows -
[
{
"id": 1,
"name": "Name 1",
"type": "1"
},
{
"id": 2,
"name": "Name 2",
"type": "2"
},
{
"id": 3,
"name": "Name 3",
"type": "2"
},
{
"id": 4,
"name": "Name 4",
"type": "1"
},
{
"id": 5,
"name": "Name 5",
"type": "2"
}
]
Here is the template to render the data -
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>type</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let d of data;">
<td width="30">{{ d.id }}</td>
<td width="80">{{ d.name }}</td>
<td>{{ getType(d.type) }}</td>
</tr>
</tbody>
</table>
As you can see, the last column will print some string based on the type, here goes the method -
/**
* Return string based on the type
*/
getType(type: string) {
console.log("modify data");
if (type === "1") {
return "First";
} else if (type === "2") {
return "Second";
}
}
Once, the component loads, this method prints "modify data" multiple times. Here is the snippet from the console.
Not sure if this is a common or an angular bug. Why is this method getting triggered 20 times?
Upvotes: 0
Views: 841
Reputation: 201
This is not actually a bug, but a feature that Angular offers and is related to the concept of Change Detection and Rendering of Virtual DOM.
But to put it simply, if you provide a function in HTML, Angular keeps listening to it. What does that mean? It means that the function keeps getting executed! And that's why you see 20 logs in the console. If you interact with the app further or do some more actions, you might even see it 100 times!
FIX: Don't use the variable 'data' directly in HTML. Let it remain as a master source. Instead declare another variable like 'displayData' and populate it from 'data' with objects having the fields you want to display in HTML. Eg: displayData = [{id: 1, name: 'test', typeDisplayed: 'First'}, {id: 2, name: 'test2', typeDisplayed: 'Second'}]. Although looping once over 'data' would take up resources in the beginning, it will just be a one time activity. After that, no further calls/listening would be needed.
I suggest this because, if you have 1000 rows in your table, getType() will keep getting called for every row and that would be affect the page performance more adversely than looping over 1000 rows only once and preparing displayable data. Thus, its better to render the td's similar to id and name and not have function calls in HTML unless absolutely necessary.
Why is this 'listening' actually a feature? Let's say you want to hide/show a HTML element(like a notification) as soon as some value gets changed or meets a certain condition. In such cases, continuously listening to a function would be very useful!
Upvotes: 2