No announcement yet.
  • Filter
  • Time
Clear All
new posts

    Grid data disappears after saving record

    Using SmartClient 13 LGPL (one of the latest versions), I have created a grid using a global data source instance "CUSTOMERS_DS". When the grid is displayed, its "data" property (a ResultSet instance) has a "localData" property with length 25 and a "allRows" property with length 25.

    I also have a ValuesManager linked to several DynamicForms with that same global data source instance "CUSTOMERS_DS". When I save a new record via valuesManager.submit(), the length of the "localData" property of the result set becomes 1. The "allRows" property of the result set is 26. The grid only shows the created record.

    If I create a second record, localData increases to 2 and allRows to 26.

    Any idea what I could be doing wrong?

    Well, that's a bit of a "whodunnit" given the lack of information. But overall, it sounds like criteria has been applied to the grid to eliminate all but the newly created record.


      I think I've found the cause: the grid has an implicit criterion on a field which itself is not necessary in the grid so it isn't part of the data. When I save the form, all grid data lacking that implicit criterion field are removed. Is there a way to avoid this behavior? I've already disabled client filtering via the "dataProperties" property of the grid (useClientFiltering = false).


        I've just noticed that "useClientFiltering" property is also available directly on the grid and I've tried it, but that doesn't seem to matter.


          Setting "neverDropUpdatedRows" for the "dataProperties" property seems to be a fix for my situation. But still wondering if my approach is wrong. And with that I mean: retrieving records with the minimum number of fields needed for the application user. And in my case also not retrieving fields that the grid is implicitly filtered by.


            Performance-wise, it is generally far more efficient to send back additional data, if that allows client-side functionality to avoid additional requests to the server entirely.

            This is especially true for larger datasets or more complex queries, where the DB may need to consult millions of records to return ~100 records to the client. It can easily be 10x, 100x or even 1000x better to send a few more columns, as opposed to doing a second query (let alone a 3rd or 4th).

            In addition, when a client filter or sort is done, the user gets an instant response, even if the network or server is slow.

            Basically, the only time it makes sense to turn off client filtering is if the client cannot replicate server filtering - for example, the server is doing full-text search, or comparing molecular structures, etc, and that algorithm is not available on the client. Even then, dataSourceField.filterOn can be set so that the client can still perform filtering on some fields, rather than just always having the server do filtering.

            To learn more about how best to optimize with SmartClient (and web applications in general), this article is basically "the Bible" on the topic:



              Thanks for your reply. I've read the article and I understand most of it. The client side filtering is a powerful mechanism, but I do wonder how it handles the situation where other users change data.


                As an example of the point I made above, I've changed the example a bit into this:

                  height: '100%',
                  members: [
                      autoFetchData: true,
                      dataSource: 'supplyItem',
                      ID: 'dsListGrid'
                      click() {
                      title: 'Refresh me!'
                  width: '100%'
                When the button is clicked, the logging is shown but no server request is made (because the criteria haven't changed). I'm wondering if this is conceptually right, given that the data might have been changed by external systems (or users with other browsers).


                  Yes, it's 100% conceptually right.

                  The possibility of the user seeing stale data in web applications has existed since the web began - the second the data arrives, it may be stale. Also, even before we had web applications, there was the Back button.

                  Web apps have always had to choose between staleness vs performance, and the tradeoffs are different for different use cases: if the user is looking at their own data, you generally cache indefinitely, vs if you are building a securities trading system, you usually use Real-Time Messaging to stream updates continuously.

                  Various other use cases fall in between. With data that is edited by multiple people, but where real-time updates aren't needed, strategies such as "long transactions" are typically deployed to avoid inadvertently overwriting newer data with older.

                  SmartClient makes it very very easy to hit anywhere along the performance vs staleness continuum you need, and indeed, makes the maximum achievable performance much, much higher than any other web framework.


                    I understand that records retrieved might be stale as soon as they arrive, but what call/mechanism would you advice to enforce a reload of the grid via the server? My use case is quite simple: a (HTML) webshop where customers place orders and a SmartClient application showing those orders to the employees that will handle them. Calling fetchData() doesn't show the latest information. I've experimented with invalidateCache() and refreshData() but both had their (dis)advantages. The latest I've tried and that seems to work fine, is calling this.setData([]) before this.fetchData(). Is this a correct way?


                      The suggestion to use invalidateCache(), and the unusual case for which setData([]) might be used, are both covered literally right in the docs for ListGrid.fetchData().

                      Neither invalidateCache() nor refreshData() has "disadvantages", they are just methods used to do different things. However, if you perceive either one to have some kind of flaw, please start a new thread on that.


                        Thanks for the reply! I will use the setData([]) call then, not understanding why it is unusual actually. With (dis)advantages I meant something similar like you described. invalidateCache() has no callback argument, which fetchData() has. And I also had some situations of double fetches as described at the end of fetchData() docs.


                          You can only get double fetches via the invalid usage described. As you seem to know, refreshData() gives you a callback. Both methods fire multiple events such as dataChanged(), which may fire at better times for the logic you want to attach - see the docs for details.

                          As the docs also describe, setData([]) followed by fetchData() is for a specific circumstance. If you aren’t in that circumstance, then you shouldn’t need to do that, and if you feel that you do, that could indicate usage errors elsewhere.