Search code examples
angulardomngfor

`ngFor` creates more items


I use Angular 10 and the *ngFor directive to create a list of elements. Whenever the input array changes, I do something with the element. E.g:

ngAfterViewInit() {
  this.elements.changes.subscribe(t => {
    this.loadElementInfos();
  })
}

If I set a break-point inside the function, occasionally I see that *ngFor actually adds the new elements to the list, and then discards the old elements.

e.g:

old-element-0
old-element-1
old-element-2
old-element-3
new-element-0
new-element-1
new-element-2
new-element-3

And a millisecond later the old elements are discarded. Is there any chance to control that behavior of ngFor to not do that?

new-element-0
new-element-1
new-element-2
new-element-3

Solution

  • If we need at some point to change the data in the collection, Angular needs to remove all the DOM elements that associated with the data and create them again. That means a lot of DOM manipulations especially in a case of a big collection, and as we know, DOM manipulations are expensive.

    You can help Angular to track which items added or removed by providing a trackBy function like this:

    app.component.ts

    import {Component, NgModule} from '@angular/core'
    import {BrowserModule} from '@angular/platform-browser'
    
    @Component({
      selector: 'my-app',
      template: `./my-app.html`,
    })
    export class App {
      collection = any[];
      constructor() {
        this.collection = [{id: 1}, {id: 2}, {id: 3}];
      }
    
      trackByFn(index, item) {
        return index;
      }
    }
    

    app.component.html

    <ul>
     <li *ngFor="let item of collection;trackBy: trackByFn">{{item.id}}</li>
    </ul>
    

    For more understanding see this helpful Article: Improve Performance with trackBy