# Persisting the State of the Grid

## Environment

<table>
    <tbody>
	    <tr>
	    	<td>Product</td>
	    	<td>Progress® Kendo UI Grid</td>
	    </tr>
    </tbody>
</table>

## Description

How can I persist the state and column configuration of the Kendo UI for Angular Grid?

## Solution

> Starting with `v19.0.0`, the Grid includes a built-in feature for persisting its state and column configuration, making it easier to save and restore user preferences. For more details, refer to the [State Management](https://www.telerik.com/kendo-angular-ui/components/grid/persist-state) article.

To persist the state and column configuration of the Kendo UI Grid for Angular, or load its previously stored settings, use either of the following approaches:

* [Use the dedicated methods](https://www.telerik.com/kendo-angular-ui/components/knowledge-base/persist-state#using-dedicated-methods)
* [Handle the events of the Grid](https://www.telerik.com/kendo-angular-ui/components/knowledge-base/persist-state#handling-grid-events)

### Using Dedicated Methods

To access the current Grid state, use a component field in the respective `State` object. To access the current columns configuration, use the `grid.columns` field.

1. Create a custom `GridSettings` object by using custom logic. You can further process and store `GridSettings` through a service. The following example demonstrates how to store the Grid settings in the `LocalStorage` of the browser. You can use the same approach to persist the settings elsewhere too.

   ```ts
   public saveGridSettings(grid: GridComponent): void {
       const columns = grid.columns;

       //add only the required column properties to save local storage space
       const gridConfig = {
           state: this.grid1Settings.state,
           columnsConfig: columns.toArray().map(item => {
               return <ColumnSettings> {
               field: item["field"],
               width: item["width"],
               _width: item["_width"],
               title: item["title"],
               filter: item["filter"],
               format: item["format"],
               filterable: item["filterable"],
               orderIndex: item["orderIndex"]
               };
           })
       };

       this.persistingService.set('gridSettings', gridConfig);
   }
   ```

   ```ts
   const getCircularReplacer = () => {
       const seen = new WeakSet();
       return (key, value) => {
           if (typeof value === "object" && value !== null) {
               if (seen.has(value)) {
                   return;
               }
               seen.add(value);
           }
           return value;
       };
   };

   @Injectable()
   export class StatePersistingService {
       public get<T>(token: string): T {
           const settings = localStorage.getItem(token);
           return settings ? JSON.parse(settings) : settings;
       }

       public set<T>(token: string, gridConfig: GridSettings): void {
           localStorage.setItem(token, JSON.stringify(gridConfig, getCircularReplacer()));
       }
   }
   ```

2. Load the previously stored settings (if any) and map them so that the Grid can be accordingly updated.

   ```html
   <button
           kendoButton
           *ngIf="savedStateExists"
           (click)="grid1Settings = mapGridSettings(persistingService.get('gridSettings'))">Load saved state</button>
   ```

   ```ts
   public mapGridSettings(gridSettings: GridSettings): GridSettings {
       const state = gridSettings.state;

       return {
       state,
       columnsConfig: gridSettings.columnsConfig.sort((a, b) => a.orderIndex - b.orderIndex),
       gridData: process(sampleProducts, state)
       };
   }
   ```

The following example demonstrates the complete implementation of the approach.

[Demo Source](https://demos.telerik.com/kendo-angular-ui/demos/knowledge-base/persist-state/source.txt)

### Handling Grid Events

1. Handle the events of the Grid which are emitted as a result of user interaction.

   ```ts
   public dataStateChange2(state: State): void {
       this.grid2Settings.state = state;
       this.grid2Settings.gridData = process(sampleProducts, state);
       this.saveGrid2();
   }

   public onReorder(e: any): void {
       const reorderedColumn = this.grid2Settings.columnsConfig.splice(e.oldIndex, 1);
       this.grid2Settings.columnsConfig.splice(e.newIndex, 0, ...reorderedColumn);
       this.saveGrid2();
   }

   public onResize(e: any): void {
       e.forEach(item => {
       this.grid2Settings.columnsConfig.find(col => col.field === item.column.field).width = item.newWidth;
       });

       this.saveGrid2();
   }
   ```

2. Save the latest state in the event handlers.

   ```ts
   private saveGrid2(): void {
       const grid2Config = {
       columnsConfig: this.grid2Settings.columnsConfig,
       state: this.grid2Settings.state
       };

       this.persistingService.set('grid2Settings', grid2Config);
   }
   ```

The following example demonstrates the complete implementation of the approach.

[Demo Source](https://demos.telerik.com/kendo-angular-ui/demos/knowledge-base/persist-state-approach-2/source.txt)
