Columns Headertext when loading persistence back to the grid

Hi
Is this the correct way to load back grid's persistence?
            var setView = this.user.settings.persistences[0];
            this.$refs.gridObj.$el.ej2_instances[0].setProperties(JSON.parse(setView[0].structure));
            this.$refs.gridObj.ej2Instances.dataSource = this.gridData;

When I do the above, the header text of the columns are lost.
Also, ValueAccessor events are not triggered causing both headers and content to be not aligned with what it was from before assigning the
persistence.

If I load the persistence wrong, let me know.
Thanks


32 Replies

SK Sujith Kumar Rajkumar Syncfusion Team May 19, 2020 07:25 AM UTC

Hi Amos, 

Greetings from Syncfusion support. 

You can get the persisted data from the Grid using its getPersistData method. And to restore the persistence to the Grid you need to parse the persisted data to JSON object and send it to its setProperties method as demonstrated in the below code snippet, 

var savedProperties; 
 
document.getElementById('save').addEventListener('click', function (args) { 
        // Persist data is stored in a global variable 
        savedProperties = JSON.parse(this.$refs.grid.ej2Instances.getPersistData()); 
}); 
 
document.getElementById('restore').addEventListener('click', function (args) { 
        // Stored persist data is restored to the grid 
       this.$refs.grid.ej2Instances.setProperties(savedProperties); 
}); 

The persist data does not contain/store the properties like, column template, column formatter, header text, value accessor since these values can be mapped as id or method that is defined in the application level or even modified and hence cannot be maintained. So if you wish to restore all these column properties then you can achieve it by cloning the grid’s columns property using JavaScript Object’s assign method and storing this along with the persist data and while restoring the settings this column object needs to be assigned to the grid’s columns property to restore the column settings. This is demonstrated in the below code snippet, 
 
var savedProperties; 
var savedColumns; 
 
document.getElementById('save').addEventListener('click', function (args) { 
        // Persist data and column model are stored in global variable 
        savedProperties = JSON.parse(this.$refs.grid.ej2Instances.getPersistData()); 
        savedColumns = Object.assign([],this.$refs.grid.ej2Instances.columns); 
}); 
 
document.getElementById('restore').addEventListener('click', function (args) { 
        // Stored persist data and column model are restored to the grid 
       this.$refs.grid.ej2Instances.setProperties(savedProperties); 
        var restoreCols = Object.assign([], savedColumns); 
       this.$refs.grid.ej2Instances.columns = restoreCols; 
}); 


Please get back to us if you require any further assistance. 

Regards, 
Sujith R 



AM Amos May 19, 2020 01:51 PM UTC

2 things, maybe related

1. I set :enablePersistence="true" - when I go out of the page and then back, the selected row from before is marked as selected but actually it's not. 2 examples with single selection grid:
a. row x is selected. I go out and in again. row x looks selected. clicking on row x. it is still selected. clickon on it again, the selection is gone.
b. row x is selected. I go out and in again. row x looks selected. clicking on row y, both are selected. actually only row y is selected but both looks  selected.

2. I tried your solution with saving/loading grid persistence. I also defined :rowSelected="rowSelected" event.
When restoring using your code
            this.$refs.gridObj.$el.ej2_instances[0].setProperties(JSON.parse(setView[0].structure));
            this.$refs.gridObj.ej2Instances.columns = Object.assign([], setView[0].columns);

I see the following error:
vue.esm.js?a026:1897 TypeError: Cannot read property 'getAttribute' of null
    at VueComponent.rowSelected (VM2546 mycodepage.vue:448)
    at Observer.notify (observer.js?811a:99)
    at Grid.Base.trigger (base.js?3923:181)
    at VueComponent.GridComponent.trigger (grid.component.js?c041:85)
    at Selection.onActionComplete (selection.js?afc0:100)
    at Selection.selectRowCallBack (selection.js?afc0:295)
    at Selection.clearRowSelection (selection.js?afc0:760)
    at Selection.clearRow (selection.js?afc0:537)
    at Observer.eval (selection.js?afc0:254)
    at Observer.notify (observer.js?811a:102)


SK Sujith Kumar Rajkumar Syncfusion Team May 20, 2020 11:15 AM UTC

Hi Amos, 
 
Query – 1: I set :enablePersistence="true" - when I go out of the page and then back, the selected row from before is marked as selected but actually it's not. 
 
We checked your reported problem but unfortunately were unable to reproduce it from our end as the selection was maintained properly with persistence enabled. Please check below video demo in your mentioned scenarios for reference, 
 
 
 
We suspect your reported issue might be occurring due to duplicate packages in your application. So we suggest to follow below steps to clear duplicate package and update NPM package 

  1. Delete package.lock.json file from your application.
  2. Remove the @syncfusion  package folder from the node_modules.
  3. Use same version for all components in package.json file.
  4. Then install the new packages.

Or please refer to the steps mentioned in the below documentation link. 

 
Query – 2: I tried your solution with saving/loading grid persistence. I also defined :rowSelected="rowSelected" event.When restoring using your code I see the following error 
 
From the error you had mentioned we could see that it is thrown because a condition checked with an element in the rowSelected event defined in the application is not present there. So can you please modify the code to execute the condition only if the required element is present to resolve the problem. 
 
If we misunderstood your query or if problem still persists please get back to us. 
 
Regards, 
Sujith R  



AM Amos May 20, 2020 01:59 PM UTC

Both issues were indeed a bug inside my rowSelected event, I fixed that but I'm back to square one where the view is updated ok but the columns don't show the correct header text and the valueAccessor is not executed.

Checking the column's object that is stored (Object.assign([],this.$refs.grid.ej2Instances.columns); ), I see the following data
  1. allowEditing: true
  2. allowFiltering: true
  3. allowGrouping: true
  4. allowReordering: true
  5. allowResizing: true
  6. allowSearching: true
  7. allowSorting: true
  8. autoFit: false
  9. disableHtmlEncode: true
  10. enableGroupByFormat: false
  11. field: "field1"
  12. foreignKeyField: "field1"
  13. index: 9
  14. showColumnMenu: true
  15. showInColumnChooser: true
  16. sortDirection: "Descending"
  17. textAlign: "center"
  18. type: "string"
  19. uid: "grid-column9"
  20. visible: true
As you can see, headerText is missing and also the fact that there should be a valueAccessor is not there so obviously it shows the field name as the header text and the valueAccessor is not executed.

Please advice



SK Sujith Kumar Rajkumar Syncfusion Team May 21, 2020 09:31 AM UTC

Hi Amos, 

Thanks for the update. 

We could not reproduce this problem from our end as the header text and value accessor functions were restored properly. Please check below video for your reference, 


Please check the below image that shows the header text and value accessor properties in the column object that is getting restored, 

 

Modified sample with value accessor functions for your reference, 


Can you please share us the following information to validate further on this problem, 

  • Please share the package.json file of your angular application and the one that is present inside the node_modules/@syncfusion/ej2-grids folder of the angular application.
  • Can you please check with the sample provided above and let us know if it achieves your requirement.
  • Since you have enabled persistence in the Grid we suspect the old grid settings from cached memory are getting restored causing the reported problem. As the persist settings are manually restored here we suggest you to remove the enablePersistence property set in the Grid, clear the local browser cache and then run your application to see if the problem is resolved.
  • Grid code file.
  • If possible provide us a simple sample to replicate problem or try reproducing it in the above provided sample.

Let us know if you have any concerns. 

Regards, 
Sujith R 



AM Amos May 22, 2020 09:54 PM UTC

OK, apparently the problem is with JSON.Stringify of the columns object

I do the following to save the stored structure to the db using a rest api, see below code and marked line. I can't simply send a json as the parameter so I stringify it.
          let structs = this.user.settings.gridStructures;
            structs.push({
                viewName: internalViewName,
                structure: JSON.parse(this.$refs.gridObj.ej2Instances.getPersistData()),
                gridColumns: Object.assign([], this.$refs.gridObj.ej2Instances.columns)
            });
            this.$postCall({
                command: "setUserSettings",
            settings: JSON.stringify(this.user.settings)
           })


I keep this.user.settings in the store and I send it to the server so it can save it to the db.
this.user.settings.gridStructures is correct at the marked line but JSON.stringify messes it up in a weird way.
After stringify, gridColumns contains getPersistData().columns instead of an object that contains headerText and valueAccessor etc...

Any idea what am I doing wrong? Thanks


SK Sujith Kumar Rajkumar Syncfusion Team May 26, 2020 11:08 AM UTC

Hi Amos, 
 
On performing JSON stringify to the columns the grid column model will be changed into an object type thus losing all the instances of template, header text and value accessor stored since these are defined in the application level and cannot be maintained in the string. Hence while restoring this object these settings will not be properly restored. You can see the difference for the column model and parsed column object in the below image,  
 
   
 
So for this case, you would need to store the template, header text, value accessor properties for the columns separately while saving the state and re-assign these values to each of the column object since the column order will be the same in order to restore them. This is demonstrated in the below code snippet, 
 
var colValues;  
  
document.getElementById("save").addEventListener("click", args => {  
                  .  
                  .  
        colObject = Object.assign([], grid.columns);  
        colObject.filter((col) => colValues.push({ "template": col.template, "headerText": col.headerText }))  
        savedColumns = JSON.stringify(colObject);  
});  
  
document.getElementById("restore").addEventListener("click", args => {  
        var columnObj = JSON.parse(savedColumns);  
        var i = 0;  
        while (i < columnObj.length) {  
            columnObj[i].template = colValues[i].template;  
            columnObj[i].headerText = colValues[i].headerText;  
            i++;  
        }  
        grid.setProperties(savedProperties);  
        grid.columns = columnObj;  
});  
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



AM Amos May 26, 2020 12:15 PM UTC

I want to make sure I understand the concept:

1. The user goes to the windows with the grid. The first thing I do is store the columns' headerText, template and ValueAccessor in the localstorage as json.
colObject = Object.assign([], grid.columns);
colObject.filter((col) => colValues.push({ 
"template": col.template, "headerText": col.headerText }))
colValues should be stored as json into the localstorage

2. The user reorder the columns, sort column X and save this view (name: test) . I should save the persistData() (which is a string) to the db.

3. The user logs out and after a day he logs in.

4. The user go to the window with the grid. When that happens, point 1 above happens again, meaning updating localstorage with the 3 properties of all columns.

5. The user is selecting to show view "test". I take the persistData I stored previously and do .setProperties(...).  This will change the grid columns (order/sort) but without headerText, template and valueaccessor.

6. I then should take the json from localStorage (point1) and update the columns:
var i = 0;
while (i < columnObj.length) {
  
columnObj[i].template = colValues[i].template; 
   columnObj[i].headerText = colValues[i].headerText;

  
i++;
}  

question 1: Because getPersistData already contains the columns object, in the right order/sort, there is no need to store also the column, right?

question 2: Because the user enters the window with the default view but he can save as many views as he wants, the order of the columns may be different between the views and the columns order from point 1 (localstorage). How can I make sure that the correct column gets the correct template/headerText/ValueAccessor? Maybe based on the field name of the column?

question 3: If later on I will add a new column to the grid that was not saved in getPersistData, how will the grid behave after .setProperties(...) of an object without this new column?

Thanks



SK Sujith Kumar Rajkumar Syncfusion Team May 27, 2020 07:26 AM UTC

Hi Amos, 
 
Query – 1: Because getPersistData already contains the columns object, in the right order/sort, there is no need to store also the column, right? 
 
If you are going to stringify and store the persist data then you need not store the column object as stringifying this anyhow will remove the header text, template properties. So for this case you need to store only the persist data and the required properties(header text, template) from the column object. 
 
Query – 2: How can I make sure that the correct column gets the correct template/headerText/ValueAccessor? Maybe based on the field name of the column? 
 
Yes you can store the field property also in the local storage along with column values and compare it while assigning these properties. Alternatively you can also use a unique name while storing the persist data and the column values in local storage. Then you can use this unique name to identify the column values for the corresponding persisted data. 
 
Query – 3: If later on I will add a new column to the grid that was not saved in getPersistData, how will the grid behave after .setProperties(...) of an object without this new column? 
 
For this case the newly added column will be removed from the Grid as it is not present in the persisted data. So if this column also needs to be restored then the updated persist data at that point must be replaced with the previous persisted data. This can be identified using a unique name as mentioned in the last query. 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



AM Amos May 27, 2020 09:35 AM UTC

1. I will try to implement your solution and see if it makes sense.

2. So instead of just colObject.filter((col) => colValues.push({ "template": col.template, "headerText": col.headerText })) I should also add col.fieldName as the unique key so I can later identify it for attaching the correct properties to the relevant field. Also col.ValueAccessor should be added ofcourse.

3. So the user stored fields A B C. Now a new version comes out with fields A B C D.
If I understand you correctly, A B C will be visible and D will be invisible, but the user will be able to select it from the column chooser. Is this correct or column D will be completely invisible to the user?


SK Sujith Kumar Rajkumar Syncfusion Team May 28, 2020 08:28 AM UTC

Hi Amos, 
 
Thanks for the update. Please let us know if you face any problems in the first query. As for your other queries, 
 
Query – 2: So instead of just colObject.filter((col) => colValues.push({ "template": col.template, "headerText": col.headerText })) I should also add col.fieldName as the unique key so I can later identify it for attaching the correct properties to the relevant field. Also col.ValueAccessor should be added ofcourse. 
 
Yes you would need to store something like below for restoring these properties, 
 
colObject.filter((col) => colValues.push({ "template": col.template, "headerText": col.headerText, "field": col.field, "valAcc": col.valueAccessor }))  
 
 
Query – 3: If I understand you correctly, A B C will be visible and D will be invisible, but the user will be able to select it from the column chooser. Is this correct or column D will be completely invisible to the user? 
 
Considering your scenario the persisted data contains A, B, C fields and a new field D is added dynamically resulting in 4 fields in the Grid. Now if you restore the same persisted data again only A, B and C fields will be restored, the D field will not be restored in the Grid as it will not be available in the persisted data. So if you need this D field also to be restored next time in the persisted data. Then you either need to store this as a new state for the persisted data or replace the previous persisted data which contains - A, B and C fields with the current persist data that contains fields – A, B, C and D. 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



AM Amos May 28, 2020 09:17 AM UTC

3. The scenario is the following:
a. The user enters the grid and see A B C D. In this step, I store internally the relevant props.
b. The user selects to see view: test. This view was created before D existed. persistsData of that view does not contain it so D will be removed from the grid. It won't even appear in the column selector?

The user can have several views and I can add several new fields between version, this will be a nightmare to maintain. Unless I'm missing something.


SK Sujith Kumar Rajkumar Syncfusion Team May 29, 2020 07:20 AM UTC

Hi Amos, 

This is similar to replacing values in a variable. Consider the below example for better understanding, 

An array “Info” has values [“a”, “b”, “c”] which is persisted locally as “View1”. Now a new value is pushed into the array “Info” which now becomes – [“a”, “b”, “c”, “d”]. But the persisted data “View1” still has this – [“a”, “b”, “c”]. So now if the persisted data(“View1”) is assigned to “Info” array it will contain only [“a”, “b”, “c”]. The value “d” will not be present here. Similarly when the persisted data does not contain the newly added column “D” then it will not be present when it is restored to the Grid columns. 

So what you need to do here to persist the updated data is when the new value “d” is added to the array – “Info” you need to update the persisted data - “View1” with this updated value. Considering the Grid case when new fields are added, you need to replace the old persisted data with the updated persisted data as we had mentioned in our previous update. You need not store a new view each time new fields are added but only need to replace the current view with the updated persist data. 

We hope you understood the concept we tried to explain here. If not please get back to us. 

Regards, 
Sujith R 



AM Amos May 29, 2020 08:02 AM UTC

Your logic and explanation is clear, but the grid's persistdata and the columns are much more complex than just [A,B,C] :-)
updating the stored views with the new persistData will "remove" all previous settings like sort,group, filter meaning I need to add the new field manually.

1. I will need to store the current/default view when entering the window.

Now I have 2 options:
2.a. When the user selects to show a (stored) view, I should update the persistData and then loop the object from point 1 to see if there are new columns and if there are, add them manually to the persistData and save it back to the server.

2.b. Loop all the user's stored views and if there are new columns, update all of them manually and save them back to the server. This way when he selects a view, the new columns are already there.

All the above, with the consideration of headerText, valueaccessor and template. This is a bit complex algorithm. I wonder if there's a way for you to add such a feature where I assign columns from one persistData (stored) to another (grid) in a way that if there are columns in the target (grid), don't touch them. What do you think?


SK Sujith Kumar Rajkumar Syncfusion Team June 1, 2020 12:33 PM UTC

Hi Amos, 
 
Yes the persist data is complex than a simple [A, B, C] but since it is the same concept we explained it to you for easy understanding. As you just need to update the newly added columns to the persist data and skip the other settings like, sort, filter you would need to use one of the two options you mentioned to perform this. 
 
We are not able to clearly understand what you mean by – I wonder if there's a way for you to add such a feature where I assign columns from one persistData (stored) to another (grid) in a way that if there are columns in the target (grid), don't touch them.. So can you please elaborate on this. 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



AM Amos June 1, 2020 01:04 PM UTC

The persistData contains columns section so for example, a merge function of the grid:

grid.merge(columnsSectionFromPersist);

This will columnsSectionFromPersist and merge it into the grid. Meaning: columns that are in the grid will be overwritten and the rest of the grid's columns will remain as they are.


SK Sujith Kumar Rajkumar Syncfusion Team June 2, 2020 12:21 PM UTC

Hi Amos, 
 
Thanks for the information. 
 
You can achieve this requirement of merging the persist data columns with the Grid’s columns by extending both of them using the base’s extend method. On performing this action you can get the merged data for both of them now since the persist data will be of array of objects type and the Grid columns will be of column model object type you need to JSON stringify and parse them back before assigning them to the Grid columns(To make the objects of the same type). This is demonstrated in the below code snippet where the persist data is stored on initial dataBound and a button(‘Add new column’) is defined for dynamically adding a new column to the Grid. Another button(‘Merge columns’) is rendered on clicking which both the persist data columns and Grid columns are extended and then assigned to the Grid using its setProperties method. 
 
var initialAdd = true; 
 
// Add new columns button click 
document.getElementById('add').addEventListener('click', function(args) { 
      if (initialAdd) { 
        // New column is added to the Grid 
        grid.columns.push({ field: 'CustomerID', headerText: 'Customer ID' }); 
        grid.refreshColumns(); 
        initialAdd = false; 
      } 
}); 
 
// Merge columns button click 
document.getElementById('merge').addEventListener('click', function(args) { 
      // Initially persisted data 
      var persistData1 = JSON.parse(persistData); 
      // Grid column object is converted to array of column object 
      gridColumns = Object.entries(gridColumns).map(e => e[1]); 
      persistData1.columns[3].headerText = "Amount"; 
      // Grid column object is extended with persisted columns 
      var newData = ej.base.extend(gridColumns, persistData1.columns); 
      // The extended data is assigned to the Grid columns 
      grid.setProperties({ columns: JSON.parse(JSON.stringify(newData)) }) 
}); 
 
Sample for your reference, 
 
 
Note: Since this is a sample-level requirement this support cannot be provided within the source 
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



AM Amos June 20, 2020 08:05 AM UTC

I finally had time to get to this and I encountered 2 issues:

When loading a saved view, I had to add
this.$refs.gridObj.ej2Instances.refresh();
for the grid to show the headers correctly (headerText), otherwise, the field remain as the header title.
When the saved view is shown, only the first row has doubled its height while all the other rows have the same height.
Any idea what to look for in order to see what might be causing this?


the arrow marked alt-row was not there, I added it manually (but it didn't change anything).
style height 60px is added ONLY to the first row. Not sure why.

-----
When the stored view has a filter, something bad is happening.
I see errors coming from filter.js and resize.js. it seems that the column/field is there but its uid is not identified by the grid, causing undefined which in turn cause the red exceptions.

Here is how I load a view
        loadView(viewName) {
            var setView = this.userInfo().settings.views[viewName];
            this.$refs.gridObj.ej2Instances.setProperties(JSON.parse(setView));
            var colObject = this.$refs.gridObj.ej2Instances.columns;
            for (var col in colObject) {
                for (var storedCol in this.storedColumns) {
                    if (this.storedColumns[storedCol].field != colObject[col].fieldcontinue;
                    colObject[col].headerText = this.storedColumns[storedCol].headerText;
                    colObject[col].valueAccessor = this.storedColumns[storedCol].valueAccessor;
                    colObject[col].template = this.storedColumns[storedCol].template;
                    break;
                }
            }
            this.$refs.gridObj.ej2Instances.refresh();
        },

Here is how I save the default view + props for later use (right after setting the data to the datasource
                            var colObject = Object.assign([], this.$refs.gridObj.ej2Instances.columns);
                            colObject.filter((col=>
                                this.storedColumns.push({
                                    field: col.field,
                                    headerText: col.headerText,
                                    valueAccessor: col.valueAccessor,
                                    template: col.template,
                                })
                            );
                            this.defaultView = this.$refs.gridObj.ej2Instances.getPersistData();




SK Sujith Kumar Rajkumar Syncfusion Team June 22, 2020 11:27 AM UTC

Hi Amos, 

We could not reproduce your reported problems. So can you please let us know on what state of the Grid you are storing the persist data and on what state of the Grid you are restoring it so that we can identify your exact scenario and validate further from our end. 

Let us know if you have any concerns. 

Regards, 
Sujith R 



AM Amos June 22, 2020 11:37 AM UTC

"So can you please let us know on what state of the Grid you are storing the persist data and on what state of the Grid you are restoring it"

What do you mean by on what state of the Grid?
Thanks


style="height: 60px" looks like a hardcoded thing, maybe searching for it in your code can give a hint on when it is added... Just a thought.


SK Sujith Kumar Rajkumar Syncfusion Team June 22, 2020 01:14 PM UTC

Hi Amos, 

By – “On what state of the Grid” we meant the persist state of the Grid(like what all operations have you performed in the Grid before storing the persist data) that you are storing and restoring to the Grid. Sorry for not making it clear. 

Regards, 
Sujith R 



AM Amos June 22, 2020 01:33 PM UTC

The storing is done right after the gridData is set with data (not in onDataBound).
The restoring is done whenever the user decides to load one of his saved views. It can be after any action or even no action at all.

 I don't think there is a correlation between the 2 issues. One (height: 60) happens almost any time. The second one (failures) happens when there's a filter involved.
I posted the code of how I store and restore the persistData.


SK Sujith Kumar Rajkumar Syncfusion Team June 23, 2020 12:49 PM UTC

Hi Amos, 

Thanks for the information. 

We suspect the problem might be occurring due to one of the following reasons, 
  • The column model not getting properly generated on restoring the column object which replaces the property values dynamically to the Grid.
  • The stored or restored column object might be containing reference to older values which might cause problems in column generation in the Grid.

Instead of storing particular column properties, by storing the entire column object these problems can be avoided. So we suggest you to use the below initially suggested approach itself to store and restore the persist data along with the entire column object, 

saveBtnClick: function() { 
        // Persist data and column model are stored in global variable 
        this.savedProperties = []; 
        this.savedColumns = []; 
        this.savedProperties = Object.assign([], JSON.parse(this.$refs.grid.ej2Instances.getPersistData())); 
        this.savedColumns = Object.assign([], this.$refs.grid.ej2Instances.columns); 
}, 
restoreBtnClick: function() { 
        // Stored persist data and column model are restored to the grid  
        this.$refs.grid.ej2Instances.setProperties(this.savedProperties); 
        this.$refs.grid.ej2Instances.columns = Object.assign([], this.savedColumns); 
} 

Modified sample for your reference, 


Let us know if you are facing any problems with this. 

Regards, 
Sujith R 



AM Amos June 24, 2020 07:11 PM UTC

This is what I'm doing when the user enters the window, right after I set the data to the datasource (NOT IN dataBound)
this.storedColumns = Object.assign([], this.$refs.gridObj.ej2Instances.columns);
this.defaultView = Object.assign([], JSON.parse(this.$refs.gridObj.ej2Instances.getPersistData()));
I then change something (sort a field ascending), and save it as a view:
let structs = Object.assign([], this.userInfo().settings.itemsStructures);
structs.push({
viewName: internalViewName,
   structure: Object.assign([], JSON.parse(this.$refs.gridObj.ej2Instances.getPersistData())),
   columns: Object.assign([], this.$refs.gridObj.ej2Instances.columns),
});
and I save it with JSON.stringify(this.userInfo().settings) to the db. Notice that this.userInfo().settings remains the same. I just wrap
it with JSON.stringify(). I then restore the view to the default one.
this.$refs.gridObj.ej2Instances.setProperties(Object.assign([], this.defaultView));
this.$refs.gridObj.ej2Instances.columns = Object.assign([], this.storedColumns);
this.$refs.gridObj.ej2Instances.refresh();

This seems to work but if I call that saved view
var setView = this.userInfo().settings.itemsStructures.filter(function(valueindexarr) {
return value.viewName == theViewName;
});
this.$refs.gridObj.ej2Instances.setProperties(Object.assign([], setView[0].structure));
this.$refs.gridObj.ej2Instances.columns = Object.assign([], setView[0].columns);
this.$refs.gridObj.ej2Instances.refresh();

I see a lot of
[Vue warn]: Error in callback for watcher "function () { return this._data.$$state }": "Error: [vuex] do not mutate vuex store state outside mutation handlers."
coming from the following (see below for my comment). Notice that it can be either
this.$refs.gridObj.ej2Instances.columns = Object.assign([], setView[0].columns); (loading a saved view)
or
this.$refs.gridObj.ej2Instances.columns = Object.assign([], this.storedColumns); (if I reset the view after loading the view)
Any way, it doesn't like me changing the columns object of the grid.



SK Sujith Kumar Rajkumar Syncfusion Team June 25, 2020 01:24 PM UTC

Hi Amos, 

We could not see any of the reported errors on performing the mentioned operations. Please check below video demo for your reference, 


We suspect this might be due to Strict mode or some similar settings enabled in your Vue application causing mutation errors. So can you please ensure this case with your application. Given below are some stack overflow links where similar problem is addressed 


Let us know if you have any concerns. 

Regards, 
Sujith R 



AM Amos June 25, 2020 01:35 PM UTC

Your scenario is not the same as I mentioned. When I did your scenario, I didn't have an error, the error appeared when I did one more steps of loading the saved view.

I know when the "mutation" errors appear and I did have them in the past for my store object but this one happens when calling your method for changing the columns.
Ofcourse it could be something I'm doing wrong, it's just I don't understand what it is.

Can we have a webmeeting? In the past, these meetings yielded a good outcome.
If tomorrow at 9:00 (my time, like before) is good for you, even better. If it's ok with you, let's continue with a private incident instead of here.
Thanks



SK Sujith Kumar Rajkumar Syncfusion Team June 26, 2020 05:18 AM UTC

Hi Amos, 

We have created a new incident for the last query under your Direct trac account as per your update. We suggest you to follow that for further details.  


Regards, 
Sujith R 



CO colew December 31, 2020 10:26 PM UTC

Amos did you ever fully solve this?  I'm doing pretty much the exact same thing where I'm trying to save grid settings to the db and allow a user to select views/queries they have saved.  


AM Amos December 31, 2020 10:49 PM UTC

Following is what I did, I hope it's good for what you need:

saving the default grid columns and structure right after loading the data into the grid
if (this.storedColumns.length == 0this.storedColumns = Object.assign([], this.$refs.gridObj.ej2Instances.columns);
if (this.defaultView == nullthis.defaultView = Object.assign([], JSON.parse(this.$refs.gridObj.ej2Instances.getPersistData()));


set/show the default view when the user asks for it
this.$refs.gridObj.ej2Instances.setProperties(Object.assign([], this.defaultView), true);
this.$refs.gridObj.ej2Instances.columns = Object.assign([], this.storedColumns);


saving a view
            structs.push({
                viewName: internalViewName,
                structure: JSON.parse(this.$refs.gridObj.ej2Instances.getPersistData()),
                columns: JSON.parse(JSON.stringify(this.$refs.gridObj.ej2Instances.columns)),
            });

set view when the user selects it
            this.$refs.gridObj.ej2Instances.setProperties(setView[0].structuretrue);
            this.$refs.gridObj.ej2Instances.columns = setView[0].columns;
            var colObject = this.$refs.gridObj.ej2Instances.columns;
            for (var col in colObject) {
                for (var storedCol in this.storedColumns) {
                    if (!colObject[col].visiblebreak;
                    if (this.storedColumns[storedCol].field != colObject[col].fieldcontinue;
                    colObject[col].headerText = this.storedColumns[storedCol].headerText;
                    colObject[col].valueAccessor = this.storedColumns[storedCol].valueAccessor;
                    colObject[col].template = this.storedColumns[storedCol].template;
                    break;
                }
            }



CO colew January 2, 2021 06:42 PM UTC

Thanks Amos.  This got me much closer to the final solution.  I still have a few strange things going on when switching between saved views/filters/queries like total record counts/pages being incorrect but it's working pretty well so far.


SK Sujith Kumar Rajkumar Syncfusion Team January 4, 2021 07:21 AM UTC

Hi Cole, 
 
We are glad to hear that the suggestion provided by Amos helped with your query. 
 
Regarding the problem that you are facing now, can you please share us the following information to validate further on it, 
 
  • Let us know the actions that you are performing in the Grid which is causing your reported problem case.
  • Video demonstration of the problem to understand it better.
  • Have you bound local or remote data to the Grid?
  • Grid code file.
  • Syncfusion package version used.
  • If possible share us a simple sample to replicate the problem.
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



CO colew October 22, 2021 12:11 AM UTC

Amos with this methodology do you have any issues with capturing the default view and columns if the user is directly navigating to a saved version of the grid first and switching to the default view after?


Loader.
Up arrow icon