swimlane / ngx-datatable

✨ A feature-rich yet lightweight data-table crafted for Angular
http://swimlane.github.io/ngx-datatable/
MIT License
4.63k stars 1.68k forks source link

Datatable doesn't get updated (doesn't show rows) after inserting new data into the rows array #486

Closed PatrickHuetter closed 7 years ago

PatrickHuetter commented 7 years ago

I'm submitting a ... (check one with "x")

[#] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here

Current behavior

I've made a video of the problem, you can find it here: http://encircle360share.s3-eu-central-1.amazonaws.com/Screen-Recording-2017-02-04-11-23-11.mp4

Using external pagination the data on the next pages using paginations doesn't get shown although it's already there. Only after changing the page and changing back again to the page before shows the data (view gets updated). It's also possible to scroll horizontally if the data is missing and the data will occur (view gets refreshed/updated). I think that might be a change detection problem.

Expected behavior Direct visibility of the rows/data after paginating.

Please tell us about your environment:

Mac OS X Sierra, IntelliJ IDEA

PatrickHuetter commented 7 years ago

I could find a workaround for this which lets the table update, even when it's not really fast (takes some more milliseconds). Using rows.push(...) or completely reassigning the rows array gets from the change detection detected. This problem seems to be a bug and seems to be the same problem like it is here #392 .

page(pageNumber?: number, pageSize?: number) {
   this.productService.getProducts(pageNumber, pageSize).subscribe((page) => {
      let start = pageNumber * pageSize;
      let end = start + pageSize;
      let products: Product[] = page.content;
      let firstProduct: Product = products.shift();
      let newRows: Product[] = [];
      newRows[start] = firstProduct;
      newRows.push(...products);
      this.rows = newRows;

      /* This does also work
      this.rows = [];
      this.rows[start] = firstProduct;
      this.rows.push(...products);
      */

      this.offset = pageNumber;
      this.count = page.page.totalElements;
      console.log('updated', start, end, this.rows);
    }, (error) => {
      console.error(error);
    });
}
stefmabo commented 7 years ago

Patrick, can you provide a demo? That doesn't work for me.

deeg commented 7 years ago

The code in their demo section for server side pagination is exactly what you need to do at the given time. Rather than mutating the array which is passed into the [rows] property of the table, you need to set it to be a brand new array.

If you were to fix this by allowing mutation of the array, it would not address the issue of storing all data you have loaded with server side pagination enabled. I think we should come to a decision on how we should handle that both with and without virtual scroll so there is a clear path forward for whoever works on the fixes.

amcdnl commented 7 years ago

@deeg is right, don't mutate your rows.

MorlaRamakrishna commented 7 years ago

I have followed @amcdnl suggestion by setting a brand new array for [rows] even though facing the same issue.

my code is here:

setPage(selection:any){
        this.pageNum=selection.offset;
        this.reconcileService.query({
            page: selection.offset,
            size: selection.limit}).subscribe(
            (res: Response) =>{ 
                this.tableRows.splice(0,this.tableRows.length);
                console.log(this.tableRows);
                this.abc=res.json();
                this.abc.forEach(item=>{ 
                    this.tableRows.push(item);
                });
                this.totalRows=res.headers.get('X-Total-Count');
                console.log(res.headers.get('X-Total-Count'));
                console.log(this.tableRows);
            },
            (res: Response) =>{                 
                console.log(res.json());
            }
        );
    }
ersatish commented 6 years ago

I have also faced this issue and resolve it with the help of ng-If because. When you get the latest data from server set previous data set to null and in template as a-if to controll it.