---
sidebar_position: 2
title: Store our data
---

## Use local data storage

We used our `fake-data.json` file to populate our grid, but in the next steps we will need to add/edit the data.

The easiest way would be to modify the `fake-data.json` file directly but this solution is too simple 😁.

For this we will use the `LocalStorage` of the browser.

## Using Blazored.LocalStorage

In order to facilitate its use, we will use the `Blazored.LocalStorage` nuget.

Install the package with the command `Install-Package Blazored.LocalStorage`

## Parametrer Blazored.LocalStorage

Open the `Program.cs` file and add the highlighted change:

```csharp title="Program.cs"
...

builder.Services
   .AddBlazorise()
   .AddBootstrapProviders()
   .AddFontAwesomeIcons();

// highlight-next-line
builder.Services.AddBlazoredLocalStorage();

var app = builder.Build();

...
```

## Save data to LocalStorage

Open the `Pages/List.razor.cs` file and modify it as follows:

```csharp title="Pages/List.razor.cs"
public partial class List
{
	private List<Item> items;

	private int totalItem;

	[Inject]
	public HttpClient Http { get; set; }

	[Inject]
	public ILocalStorageService LocalStorage { get; set; }

	[Inject]
	public NavigationManager NavigationManager { get; set; }

	protected override async Task OnAfterRenderAsync(bool firstRender)
	{
		// Do not treat this action if is not the first render
		if (!firstRender)
		{
			return;
		}

		var currentData = await LocalStorage.GetItemAsync<Item[]>("data");

		// Check if data exist in the local storage
		if (currentData == null)
		{
			// this code add in the local storage the fake data (we load the data sync for initialize the data before load the OnReadData method)
			var originalData = Http.GetFromJsonAsync<Item[]>($"{NavigationManager.BaseUri}fake-data.json").Result;
			await LocalStorage.SetItemAsync("data", originalData);
		}
	}

	private async Task OnReadData(DataGridReadDataEventArgs<Item> e)
	{
		if (e.CancellationToken.IsCancellationRequested)
		{
			return;
		}

		// When you use a real API, we use this follow code
		//var response = await Http.GetJsonAsync<Data[]>( $"http://my-api/api/data?page={e.Page}&pageSize={e.PageSize}" );
		var response = (await LocalStorage.GetItemAsync<Item[]>("data")).Skip((e.Page - 1) * e.PageSize).Take(e.PageSize).ToList();

		if (!e.CancellationToken.IsCancellationRequested)
		{
			totalItem = (await LocalStorage.GetItemAsync<List<Item>>("data")).Count;
			items = new List<Item>(response); // an actual data for the current page
		}
	}
}
```

## Concept: Blazor Storage

### Preserve state between browser sessions

As a general rule, persist state across browser sessions where users are actively creating data, not just data that already exists.

To persist state across browser sessions, the application must persist data in a storage location other than browser memory.
State persistence is not automatic. You must take steps during application development to implement stateful data persistence.

Data persistence is typically required only for high-value state that users have spent creating.

In the following examples, persistent state saves time or contributes to business activities:
* Multi-step Web Forms: It is cumbersome for a user to re-enter data for multiple completed steps of a multi-step web form if their state is lost. A user loses state in this scenario if they exit the form and return it later.
* Shopping Carts: Any commercially significant component of an app that represents potential revenue can be maintained. A user who loses their status, and therefore their shopping cart, may purchase fewer products or services when they return to the site later.

An application can persist only Application state. User interfaces cannot be persisted, such as component instances and their render trees. Components and render trees are generally not serializable. To persist UI state, such as the expanded nodes of a Tree View control, the application must use custom code to model the behavior of UI state as the state of the serializable application.

### State preservation location

Common locations exist for persistence state:
* Server side storage
* URLs
* Browser Storage
* In-memory state container service

### Browser storage

For temporary data that the user actively creates, a commonly used storage location is the `localStorage` & `sessionStorage` pools and the browser:
* `localStorage` is limited to the browser window. If the user reloads the page or closes and reopens the browser, the state persists. If the user opens multiple browser tabs, the state is shared across the tabs. Data is retained in `localStorage` until explicitly cleared.
* `sessionStorage` is extended to the browser tab. If the user reloads the tab, the state persists. If the user closes the tab or browser, the state is lost. If the user opens multiple browser tabs, each tab has its own independent version of the data.

:::info
`localStorage` and `sessionStorage` can be used in Blazor WebAssembly apps, but only by writing custom code or using a third-party package.
:::

:::caution
Users can view or alter data stored in `localStorage` and `sessionStorage`.
:::

### Where to find local session data

All recent browsers allow you to view local session data.

To do this, in your browser, press the `F12` key, in the new window:

* Select the `Application` tab
* In `Storage`:
	* Select `Local Storage`
	* Select your app url

You now have access to all the stored data, you can modify them as well as delete them.

![Ou trouver les données de session locales](/img/ajouter-item/local-session-location.png)
