Save/Restore columns preferences using templates

I use in my component.ts 

 actionBegin(args:SaveEventArgs): void {
 if (args.requestType === 'reorder' || args.requestType === 'columnstate' ) {
           
                let columnState = this.logGrid.getPersistData(); //get persist data 
                window.localStorage.setItem("columnState"columnState);
         
        }
    }


for save state of columns

and 
  let persistedData:objectJSON.parse(window.localStorage.getItem("columnState"));
      
        this.logGrid.setProperties(persistedData); //get persist data 
        this.logGrid.refresh(); 

for restore state.

The problem is that in my  grid there is a columun with template like this:

  <e-column field='Esito'  headerText='Esito Sync.' width='50'>
                <ng-template #template let-data>   
                                 
                   
                        <ejs-tooltip target='.e-info' position='RightCenter'>
                        <div *ngIf="data.Esito=='ERRORE' "class="statustemp e-errorecolor"
                             title=" {{data.EsitoMsg}}">
                             <span class="statustxt e-errorecolor"> {{data.Esito}}</span>
                            </div>
                         <div *ngIf="data.Esito=='COMPLETATA' "class="statustemp e-completatacolor"
                             title=" {{data.EsitoMsg}}">    
                            <span class="statustxt e-completatacolor"> {{data.Esito}}</span>
                        </div>
                         <div *ngIf="data.Esito=='WARNING' "class="statustemp e-warningcolor"
                         title=" {{data.EsitoMsg}}">    
                        <span class="statustxt e-warningcolor"> {{data.Esito}}</span>
                      </div>
                         <div *ngIf="data.Esito=='DIFFERITA' "class="statustemp e-differitacolor"
                              title=" {{data.EsitoMsg}}">    
                              <span class="statustxt e-differitacolor"> {{data.Esito}}</span>
                         </div>
                        </ejs-tooltip>
                   </ng-template>
                        

and this template no longer works after state columns restore.
Can you help me?
Thanks


7 Replies 1 reply marked as answer

SK Sujith Kumar Rajkumar Syncfusion Team November 23, 2020 07:54 AM UTC

Hi Candeloro, 
 
Greetings from Syncfusion support. 
 
Based on the query we could understand that you are trying to store and restore persisted data(along with template) to the Grid. The persisted data will lose all the instances of template, header text and value accessor in the column model 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,    
   
       
   
This is the reason why the template is not restored properly in your application. So for this case, you would need to store the template property of the columns separately, then store them to the local storage and while restoring re-assign these values to each of the column object since the column order will be the same. But since ng-template is used in the Grid the column’s template property will contain angular template instance as shown in the below image which cannot be stringified as it will result in error.  
  
   
  
So you need to store these properties in a global variable in your application without stringifying them for restoring them properly. Alternatively if you need to use the local storage to store and restore the grid properties including template then you need to use the TypeScript way to define template in the Grid. This is demonstrated in the below help documentation site,  
  
  
On using this approach the template id will only be defined in the column template property and so you can store the required properties of the column alone in the local storage which can then be restored using the below demonstrated way,  
   
onStore() {  
      var persistData = this.gridObj.getPersistData();  
     var data = JSON.stringify(persistData);  
     window.localStorage.setItem("gridPersistData", data);  
      var columns = Object.assign([], this.gridObj.columns);  
      var colValues = [];  
      // Template property of the columns is stored separately(or can be added to the same persist data item) in window local storage  
      var colData = columns.filter((col) => colValues.push({ "template": col.template }))  
     window.localStorage.setItem("gridCol", JSON.stringify(colValues));  
}  
  
onRestore() {  
     var getPersistedData = JSON.parse(window.localStorage.getItem("gridPersistData"));  
     var data = JSON.parse(getPersistedData);  
     var colsData = JSON.parse(window.localStorage.getItem("gridCol"));  
     if (data) {  
               var i = 0;  
                // Template property of the stored data is restored to the persisted column object  
                while (i < data.columns.length) {  
                    data.columns[i].template = colsData[i].template;  
                    i++;  
                }  
                // Data is restored 
                this.gridObj.setProperties(data);  
      }  
}  
 
Please get back to us if you require any further assistance. 
   
Regards,   
Sujith R  


Marked as answer

CS Candeloro Sgarlata November 23, 2020 10:43 AM UTC

Hi Sujith 

Thanks for the prompt replay.
But my store function generates the error 

core.js:6185 ERROR TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'TView'
    |     property 'blueprint' -> object with constructor 'LViewBlueprint'
    --- index 1 closes the circle
    at JSON.stringify (<anonymous>)
    at TabElencoComponent.actionBegin (tab-elenco.component.ts:685)
    at TabElencoComponent_Template_ejs_grid_actionBegin_5_listener (tab-elenco.component.html:12)
    at executeListenerWithErrorHandling (core.js:21693)
    at wrapListenerIn_markDirtyAndPreventDefault (core.js:21735)
    at SafeSubscriber.schedulerFn [as _next] (core.js:36932)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:183)
    at SafeSubscriber.next (Subscriber.js:122)
    at Subscriber._next (Subscriber.js:72)
    at Subscriber.next (Subscriber.js:49)
defaultErrorLogger @ core.js:6185
handleError @ core.js:6238
handleError @ core.js:13558
executeListenerWithErrorHandling @ core.js:21696
wrapListenerIn_markDirtyAndPreventDefault @ core.js:21735
schedulerFn @ core.js:36932
__tryOrUnsub @ Subscriber.js:183
next @ Subscriber.js:122
_next @ Subscriber.js:72
next @ Subscriber.js:49
next @ Subject.js:39
push../node_modules/@syncfusion/ej2-angular-base/src/component-base.js.ComponentBase.trigger @ component-base.js:285
setVisible @ ej2-grids.es2015.js:9842
hide @ ej2-grids.es2015.js:9804
hideColumns @ ej2-grids.es2015.js:13030
columnMenuItemClick @ ej2-grids.es2015.js:35959
notify @ ej2-base.es2015.js:1964
trigger @ ej2-base.es2015.js:5062
clickHandler @ ej2-navigations.es2015.js:2064
invokeTask @ zone-evergreen.js:399
onInvokeTask @ core.js:41264
invokeTask @ zone-evergreen.js:398
runTask @ zone-evergreen.js:167
invokeTask @ zone-evergreen.js:480
invokeTask @ zone-evergreen.js:1621
globalZoneAwareCallback @ zone-evergreen.js:1658

the line generating the error is:

   // Template property of the columns is stored separately(or can be added to the same persist data item) in window local storage  
                 var colData = columns.filter((col=> colValues.push({ "template": col.template }))  
             
                 window.localStorage.setItem("gridCol"JSON.stringify(colValues));  

Also in your answer you refer to a documentation related to the JS environment, while I am working with Angular.

Regardes 
Candeloro


SK Sujith Kumar Rajkumar Syncfusion Team November 24, 2020 07:02 AM UTC

Hi Candeloro, 
 
As mentioned in our previous update, the ng-template will generate angular template instance that will be stored in the Grid columns. So stringifying it will result in error(which you have updated). That is why we had suggested you to achieve this requirement by using one of the following approaches, 
 
  • Storing these template in a global variable in your application without stringifying them and while restoring the column model in Grid, access the angular template instance and assign it to the corresponding column’s template property.
  • Use the JavaScript approach to define, store and restore the template function. On using this approach the template id alone is needed to be defined in the column template property and so it can be properly stored and restored by following the steps suggested in our previous update.
 
Let us know if you have any concerns. 
 
Regards, 
Sujith R 



MW Meidika Wardana October 13, 2021 03:00 PM UTC

Hi, please provide source code for this approach.


  • Use the JavaScript approach to define, store and restore the template function. On using this approach the template id alone is needed to be defined in the column template property and so it can be properly stored and restored by following the steps suggested in our previous update.

Thanks


SK Sujith Kumar Rajkumar Syncfusion Team October 14, 2021 06:15 AM UTC

Hi Meidika, 
 
Greetings from Syncfusion support. 
 
Please find the below sample and source code for achieving the mentioned requirement, 
 
 
index.html 
<script id="template" type="text/x-template"> 
  <div> 
    <a rel='nofollow' href=https://en.wikipedia.org/wiki/${ShipCountry}>${ShipCountry}</a> 
  </div> 
</script> 
 
app.component.html 
<e-column field='ShipCountry' headerText='Ship Country' template='#template'></e-column> 
 
app.component.ts 
onStore() { 
    var persistData = this.gridObj.getPersistData(); 
    var data = JSON.stringify(persistData); 
    window.localStorage.setItem("gridPersistData", data); 
    var columns = Object.assign([], this.gridObj.columns); 
    var colValues = []; 
    // Template property of the columns is stored separately(or can be added to the same persist data item) in window local storage   
    var colData = columns.filter((col) => colValues.push({ "template": col.template })) 
    window.localStorage.setItem("gridCol", JSON.stringify(colValues)); 
} 
 
onRestore() { 
    var getPersistedData = JSON.parse(window.localStorage.getItem("gridPersistData")); 
    var data = JSON.parse(getPersistedData); 
    var colsData = JSON.parse(window.localStorage.getItem("gridCol")); 
    if (data) { 
        var i = 0; 
        // Template property of the stored data is restored to the persisted column object   
        while (i < data.columns.length) { 
            data.columns[i].template = colsData[i].template; 
            i++; 
        } 
        // Persisted data is restored along with column template 
        this.gridObj.setProperties(data); 
    } 
} 
 
Please get back to us if you require any further assistance. 
 
Regards, 
Sujith R 



MW Meidika Wardana replied to Sujith Kumar Rajkumar October 14, 2021 06:27 AM UTC

Hi Sujith, thanks for the reply. I already solved the template issue myself.




SK Sujith Kumar Rajkumar Syncfusion Team October 15, 2021 05:51 AM UTC

Hi Meidika, 

We are glad to hear that you were able to resolve the problem from your end and thanks for sharing the solution here. 

Regards, 
Sujith R 


Loader.
Up arrow icon