How is *ngfor works in this example

Viewed 189

I don't understand how *ngfor can run each time and output only the last added value in this example, can anyone explain to me please ? If each time the Array Numbers get updated in the setinterval function, and there for it triggers the ngfor each time, isn't supposed to output the whole array every 1000 ms ? And be like :
Number is - 0
Number is - 0
Number is - 1
Number is - 0
Number is - 1
Number is - 2
...

Instead the result is this :
Number is - 0
Number is - 1
Number is - 2
Number is - 3
...

Here is the app-root component TS

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})

export class AppComponent {

  interval = 0;
  lastNumber = 0;

  Numbers:number[] = [];

  TimeTick()
  {
    this.interval = setInterval(() =>
    {
      this.Numbers.push(this.lastNumber);
      this.lastNumber++;
    }, 1000)
  }
}

Here is the app-root component HTML

<div class="container">
  <div class="row">
    <div class="col-xs-12">
      <button class="btn btn-primary" (click)="TimeTick()">Start</button>
      <app-loop-x *ngFor="let num of Numbers" [number]="num"></app-loop-x>
    </div>
  </div>
</div>

Here is the app-loop-x TS

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

@Component({
  selector: 'app-loop-x',
  templateUrl: './loop-x.component.html',
  styleUrls: ['./loop-x.component.css']
})

export class LoopXComponent {

  @Input() number: number = 0;
}

Here is the app-loop-x HTML

<p>Number is - {{ number }}</p>
2 Answers

you shouldn't have this:

Number is - 0 Number is - 0 Number is - 1 Number is - 0 Number is - 1 Number is - 2

because every second you are pushing the value of the last number and then you do + 1 to least number (after the push)

so after 1 sec you push 0 and you +1 at lastNumber so next second you will push 1 and then next second 2 ....

this is the explanation of thoses lines

    this.interval = setInterval(() =>
    {
      this.Numbers.push(this.lastNumber);
      this.lastNumber++;
    }, 1000)

When you change the value of the array Numbers the *ngFor directive updates the output, it does not create a new output for each change.

Change propagation When the contents of the iterator changes, NgForOf makes the corresponding changes to the DOM:

When an item is added, a new instance of the template is added to the DOM.

When an item is removed, its template instance is removed from the DOM.

When items are reordered, their respective templates are reordered in the DOM.

So the "last value" it's not there anymore, cause it has been overrided with the new one.

In general if you have an array texts like ['text1', 'another text']:

<h1 *ngFor="let txt of texts">{{txt}}</h1>

This will generate two h1 tags with the values of the array.

Then if change the array to ['new text'], the same *ngFor will update and it will generate just one h1 tag with 'new text' value, and the old 'text1' and 'another text' h1 tags will dissapear from the view.

You can read more about this in the official documentation

In your particular case, you are adding elements to the DOM so it creates a new instance of the template each time you do that. So it's working just fine when it renders the whole array.

Related