Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Angular ngFor running in infinite loop when displaying array

i’m currently trying to make a Logbox for my webapp. It gets an Array of logs and should display them row by row in a div. Im using ngFor and looping trough my Array of logs and then displaying them.

My problem is now that the logs get displayed infinite times, not just 5 times (5 Array entries in list) like it should.

Does somebody have a hint what im missing?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

logs.component.html

<div class="logContent">
    <div class="row">
      <div class="col-12" *ngFor="let log of this.logService.getLogs()">
        <app-singlelog [when]="log.when" [type]="log.type" [data]="log.data"></app-singlelog>
      </div>
    </div>
  </div>

log.service.ts

export class LogService {
  private logArray = [];
  /* private logObject = {} as Log; */

  constructor(private httpservice: HttpserviceService) { 
    
  }

  public getLogs(): Array<Log> {
    this.httpservice.getLogs().subscribe(data => {
      data.forEach(index => {
        let logObject = {} as Log;
        logObject.when = index.when;
        logObject.type = index.type;
        logObject.data = index.data;
        this.logArray.push(logObject);
      })
    }
    )
    return this.logArray;
  }
}

Thanks 🙂

>Solution :

Don’t use function calls from html template to display data.
Instead, call the getLogs() function from the Angular ngOnInit() function, and store the response in a variable. Then loop on that variable:

export class LogService implements OnInit {
// ...

logs = [];

ngOnInit() {
   this.getLogs();
}

getLogs(): Array<Log> {
    this.httpservice.getLogs().subscribe(data => {
      data.forEach(index => {
        let logObject = {} as Log;
        logObject.when = index.when;
        logObject.type = index.type;
        logObject.data = index.data;
        this.logArray.push(logObject);
      });
      // assign the variable here:
      this.logs = data;

    });
}

In the template:

 <div class="col-12" *ngFor="let log of logs">
   <app-singlelog [when]="log.when" [type]="log.type" [data]="log.data"></app-singlelog>
</div>

The reason behind this is the fact that Angular calls your getLogs function on every page rendering cycle. But you should call the http request only once, when initalising the component.

Don’t forget to unsubscribe from your Observable. 😉 – corrected from the comment below.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading