2

I'm new to Angular and getting a Issue at the PrimeNG p-table.

This is my p-table

<p-table [value]="data" [lazy]="true" (onLazyLoad)="loadData($event)" [multiSortMeta]="sort" .... >

When anything changes I come in my loadData Method.

loadData(event): void {

    this.dataservice.loadData(..fields from event...).subscribe(result => {
        this.data = result.data;
        this.sort = result.sort; // <- This run into infinity loop
    })
}

So everytime I change this.sort I am coming into my loadData which will again do a request and so on.

Punching
  • 55
  • 7

1 Answers1

0

I had the same issue because I set an array variable and re-assign it.

WRONG IMPLEMENTATION

sample.html

<p-table [value]="data" [lazy]="true" (onLazyLoad)="loadData($event)" sortMode="multiple"[multiSortMeta]="multiSortMeta"> 

sample.ts

public multiSortMeta: any = [];

ngOnInit() {
  this.loadData();
}

loadData(event: any) {
  setTimeout(() => {
    if (event.multiSortMeta !== undefined && event.multiSortMeta.length > 0) {
      const reference = [...this.multiSortMeta];
      event.multiSortMeta.map((sort) => {
        const sortIndex = reference.findIndex((f: any) => { return f.field === sort.field; });
        if (sortIndex > -1) {
          reference[sortIndex].order = sort.order;
        } else {
          reference.push({ field: sort.field, order: sort.order, requireReload: true });
        }
      });
      this.multiSortMeta = [...reference]; // It cause for infinite loop
    }
    this.someService.search(this.params, this.multiSortMeta)
      .subscribe(response => {
        console.log(response);
      })
  }, 0);
} 

CORRECT IMPLEMENTATION

Here I added a flag (requireReload) to check whether to reload data or not. Once a function is called we set a flag to true to reload and once it's done then set it back to false, So another time function executes then it will doesn't reload and it breaks the loop.

sample.html NO CHANGE REQUIRED

<p-table [value]="data" [lazy]="true" (onLazyLoad)="loadData($event)" sortMode="multiple"[multiSortMeta]="multiSortMeta"> 

sample.ts

public multiSortMeta: any = [];

ngOnInit() {
  this.loadData();
}

loadData(event: any) {
  setTimeout(() => {
    // For multiple sorting
    if (event.multiSortMeta !== undefined && event.multiSortMeta.length > 0) {
      event.multiSortMeta.map((sort) => {
        const sortIndex = this.multiSortMeta.findIndex((f: any) => { return f.field === sort.field; });
        if (sortIndex > -1) {
          // When sort change
          if (this.multiSortMeta[sortIndex].order !== sort.order) {
            this.multiSortMeta[sortIndex].requireReload = true // We set a flag here to reload the data
          }
          this.multiSortMeta[sortIndex].order = sort.order;
        } else {
          // When new sort column added
          this.multiSortMeta.push({ field: sort.field, order: sort.order, requireReload: true });
        }
      });

      // Check if any of key require reload
      const requireReload = this.multiSortMeta.some((m: any) => {
        return m.requireReload;
      });

      // It will reload only when a new sort column is added or the previous one is altered
      if (requireReload) {
        this.multiSortMeta.forEach((m: any) => {
          return m.requireReload = false; // Here we false to reload so next time it will not be called and It brakes the infinite loop
        });
        this.multiSortMeta = [...this.multiSortMeta];
        this.loadService();
      }
    } else {
      // For normal pagination and stuff
      this.loadService();
    }
  }, 0);
}

loadService() {
  this.someService.search(this.params, this.multiSortMeta)
    .subscribe(response => {
      console.log(response);
    })
} 
Neel Rathod
  • 2,013
  • 12
  • 28