Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table goes blank when changing field values in v3 #820

Closed
Ulrar opened this issue Aug 17, 2021 · 13 comments
Closed

Table goes blank when changing field values in v3 #820

Ulrar opened this issue Aug 17, 2021 · 13 comments

Comments

@Ulrar
Copy link

Ulrar commented Aug 17, 2021

I'm submitting a Bug report

Your Environment

Software Version(s)
Angular 12
Angular-Slickgrid 3.0.5
TypeScript 4.3.5

Describe the Bug

When changing data in the table it sometimes goes blank, or fails to load when scrolling down.

Steps to Reproduce

I'm not sure, I've only seen that bug in production and I've been unable to reproduce it in dev & uat.
But essentially I'm just changing the values in the fields of each row, then calling invalidate() then render(). I've also tried this.rows = this.rows.slice(); with the same result.

Expected Behavior

In dev & uat the table re-renders fine and starts showing the new values.

Current Behavior

When the values change and I call invalidate & render or slice, the table snaps back to the top (or at least the scroll bar resets) and either goes completely blank, or starts showing the new values on the visible part but scrolling down reveals only a blank space. See below for an example where I've scrolled down :

image

Sorry for the black bars, not sure what I can and can't show. But as you can see I scrolled down a bit and below what I could see at the top, it's just blank now. The table is still the correct size, before changing the values and re-rendering I had lines showing correctly there.
I have 5 columns, one independent and two groups of two.

Possible Solution

I haven't found a solution yet. Filtering seems to bring the "hidden" values back so that's a workaround if you know what you're looking for, but not ideal.

Code Sample

    this.rows.forEach(row =>
      {
          row[my][complex][object] = "new value";
      });
    if (this.angularGrid != null) { this.angularGrid.slickGrid.invalidate(); this.angularGrid.slickGrid.render(); }
this.columnDefinitions = [{ id: "MyId", name: "MyId", field: "id", sortable: true, cssClass: "text-center border-right", headerCssClass: "d-flex justify-content-center", filterable: true }];

this.columnDefinitions.push({id: "MyId2", name: "Name", field: "complex.field", sortable: true, cssClass: "text-center border-right", headerCssClass: "d-flex justify-content-center", columnGroup: "group", formatter: Formatters.multiple, params: {formatters: [Formatters.complexObject, aSimpleCssFormatter]}});

I'm not sure how much that will help since the exact same code in dev & uat works flawlessly, for some reason only prod shows the issue.
I'm not seeing any differences between my uat and prod configs in angular.json so I don't know if that could be caused by optimizations. Is there a way to debug this further, or am I doing something obviously wrong ?

Note that I've had the exact same code for a while now and it was working well in v2. This started happening when I upgraded to v3.

@ghiscoding
Copy link
Owner

Sorry but since you can't provide a way to replicate & troubleshoot, I'm afraid there isn't much I can help with. The only thing I could say is why are you changing the values directly in the dataset without using the DataView methods to update (or the Grid Service)? Maybe try to use the proper methods and see if that helps, apart from that I can't provide anything here

@Ulrar
Copy link
Author

Ulrar commented Aug 17, 2021

I'm not sure what you mean, looking at the wiki DataView seems to be from slickgrid itself but I don't know what the proper methods are, I thought updating the dataset was the correct way.
Do you mean to do something like the first answer of this SO post, with a beginUpdate, updateItem on each row then endUpdate ? Would that not leave the dataset in an inconsistent state with what's actually being shown ?

@ghiscoding
Copy link
Owner

This Example uses the Grid Service to insert/update items

@ghiscoding
Copy link
Owner

ghiscoding commented Aug 17, 2021

The DataView is a SlickGrid Service that deal/communicate with the dataset, it's used internally by Angular-Slickgrid and you have 2 choices, you can use some of the Grid Service methods to insert/update or use directly the SlickGrid DataView. The only difference is that the Grid Service I created will talk to the DataView but will also call the invalidate and whatever else, basically that Grid Service is just a helper (for example updateItemById

Reasons you shouldn't change the data directly is that the DataView will become out of sync and might have some side effect.
I'm not sure that will fix your issue, but still you shouldn't change the data directly.

@Ulrar
Copy link
Author

Ulrar commented Aug 17, 2021

Thanks,

Gave this a try :

for (let index = 0; index < this.angularGrid.dataView.getLength(); index++)
{
          var row = this.angularGrid.gridService.getDataItemByRowIndex(index);
          row[my][object] = "change";
          this.angularGrid.gridService.updateItem(row);
}

And to answer my own question it looks like doing it this way also updates the dataset, no inconsistencies and no need to keep them synced manually.

I don't know if that solves the issue yet since I need to deploy to prod to find out, but I can already see this does not play nice with filtering. I've also tried using my dataset as a source instead of that for loop but in that case I get an error when I try to update a row with an id that has been filtered out.

Is there another way to update rows that would not cause issues with filtering, or should I clear the filter before the update and re-apply it after ?

@ghiscoding
Copy link
Owner

The code you used is not the most efficient way, you can use the getDataItemByRowIndex to get the item but you should do only 1 update with updateItems (from your temp data) outside of your for loop to do a bulk update which should speed up your update by quite a lot.

There shouldn't be any impact on the filtering, the filter method is kept within the DataView and the filtering should be reflected in the UI after doing the update. The Example 11 doesn't have filtering but I could add it in the future, I would expect the data in the grid to be filtered right away after an update. You can try calling dataView.refresh() but I don't think you would typically need to do that, the update should call it itself.

@Ulrar
Copy link
Author

Ulrar commented Aug 17, 2021

Right, that does work better :

this.rows.forEach(row =>
{
  row = change;
}
this.angularGrid.gridService.updateItems(this.rows);

With that it updates and the filtering stays, as expected.
I'll deploy this to prod tomorrow and see if that resolves the issue, thanks

@Ulrar
Copy link
Author

Ulrar commented Aug 18, 2021

So I've deployed it and it's interesting.
Now when loading the table looks good, I can scroll down and see the rows. But if I wait for a while and then scroll down, the table is blank.
Changing the values in the fields does not break it anymore, it even fixes the table if it's broken at that time.

I believe slickgrid does some magic to only keep the visible part of the table loaded, could that be breaking for some reason and not loading the rest of the table on scroll after some time ?

EDIT: It seems very random, most times it works perfectly fine, sometimes the part of the table not in view goes blank. Not sure if anything is making it fail

@Ulrar
Copy link
Author

Ulrar commented Aug 18, 2021

Found the cause, it's only when I open the network tab. For some reason only in prod still, but pressing F12 seems to always break the part not in view, scrolling down after only shows blank space.

@ghiscoding
Copy link
Owner

sorry but unless you provide some ways of replicating this issue, I can't help here since the github demo page is working fine and is also a prod build.

@ghiscoding
Copy link
Owner

there's maybe 2 things you can try, I can only imagine that there's possibly an event affecting the re-rendering of the grid which makes it blank.

  1. find which event triggers the render that blanks your UI, that might be hard to find, you can start by adding a bunch of console.log inside the node_module/slickgrid/slick.grid.js on each of the events.
  2. remove the grid auto-resize by fixing the grid height/width or pause the resizer
    • you can see this Example 2 to show how to Pause the Resizer
  3. is your data still all in there? You maybe want to confirm by querying the DataView, this.angularGrid.dataView.getItems()

I really can't help at all without a repro

@sapnildessai
Copy link
Contributor

sapnildessai commented Aug 28, 2021

Hi Guys,

Unfortunately even I am facing the same table blank issue in production. Everything works pretty fine when app is run using ng serve.
Table goes blank when the scroll is dragged abruptly holding the scroll handle. If scrolled using mouse wheel everything is good.
But same doesnt happen in the slick grid examples and that's weird on my setup :(. As soon as he window is resized everything is there.

Thanks

@ghiscoding
Copy link
Owner

ghiscoding commented Sep 9, 2021

The new version v3.1.0 is now released and I did couple of small changes in both lib, hopefully this will fix this issue. So I'm closing it for now. Check the new release v3.1.0 to see all new features/fixes

Cheers ⭐

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants