DEV Community

Bradley Wells
Bradley Wells

Posted on • Originally published at wellsb.com on

Blazor Write to LocalStorage

Original Article

One way to have data persist across sessions in a client-side Blazor WebAssembly application is to write to the browser’s LocalStorage or SessionStorage collection. This will allow the user to refresh or re-open the page and have the same experience as when they last left off.

In previous tutorials, you already learned how to pass application data between different pages and components during a single session, but there are situations when you may want data to persist across sessions in your client-side application. In a server-side application, you could simply save the data into a SQL database or other store. In a WebAssembly application, however, can use the browser’s LocalStorage or SessionStorage collection as a backing store.

Protecting Data Storage

Though this tutorial will not be storing sensitive data, it is good practice to encrypt stored data. ASP.NET Core provides a simple data protection stack that can be used for such purposes. In the future, it may be recommended to use a package such as Microsoft’s ProtectedBrowserStorage Nuget package, which provides data protection.

As of this writing, that package is still in early development, and it cannot target netstandard, a requirement of Mono WebAssembly. Therefore, I will be using the Blazored.LocalStorage package. Simply install it via the Package Manager Console.

Install-Package Blazored.LocalStorage

Blazor.LocalStorage Setup

To use the Blazored.LocalStorage package, you must register its service with your application’s service collection in your project’s Startup.cs file. Start by adding a using statement for the Blazored.LocalStorage namespace to the top of Startup.cs.

using Blazored.LocalStorage;

Then, register the service in the ConfigureServices() method of Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    services.AddBlazoredLocalStorage();
}

Now that the service is configured, go ahead and import the package’s namespace in the project’s _Imports.razor file. This will allow you to use the package in all your .razor components without having to explicitly add a using directive for each component.

@using Blazored.LocalStorage;

You are now ready to begin writing data to the browser’s LocalStorage collection. Open Pages/Index.razor and paste the following content.

@page "/"

<h1>Your LocalStorage Note</h1>

<textarea @bind="noteContent" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>

This will display a textarea field that will contain the content of the note. There is also a Save button, which will be used to write to the browser’s local store, and a Clear button which will clear all locally stored data.

Blazor Save to LocalStorage

To begin using Blazored.LocalStorage, inject an instance of the desired service into your page. At the top of Index.razor , add the following line:

@inject Blazored.LocalStorage.ILocalStorageService LocalStore

Now, declare a string variable to hold the contents of the textarea element, and create the event handlers that will correspond to each button’s onclick event. The shell may look like the following:

@code{
    string noteContent;
    public async void UpdateLocalStorage()
    {

    }

    public async void ClearLocalStorage()
    {

    }
}

To write an item to LocalStorage asynchronously using Blazored.LocalStorage, you will use a key-value structure.

await localStore.SetItemAsync(key, value);

where localStore corresponds to the name you assigned when injecting the instance, and key and value are both strings.

const string noteKey = "note";
string noteContent;

public async void UpdateLocalStorage()
{
    await localStore.SetItemAsync(noteKey, noteContent);
}

Blazor Clear LocalStorage

Blazored.LocalStorage also includes convenient methods for clearing individual items by key

await localStore.RemoveItemAsync(key);

and for clearing all stored items.

await localStore.ClearAsync();

Your ClearLocalStorage handler may look like the following:

public async void ClearLocalStorage()
{
    noteContent = "";
    await localStore.ClearAsync();
}

Blazor Read LocalStorage

In order for the application to populate the textarea with the value stored in LocalStorage, you must override the page’s OnInitialized() method. Specifically, to read the value asynchronously, override the async method OnInitializedAsync().

protected override async Task OnInitializedAsync()
{
}

In this method, you should assign the stored value to the binding variable you are using for the textarea element, in this case noteContent.

To fetch the value of an item from LocalStorage, you will use the item’s key as its identifier.

protected override async Task OnInitializedAsync()
{
    noteContent = await localStore.GetItemAsync<string>(noteKey);
}

The Final Product

Your completed index.razor page will look similar to the following:

@inject Blazored.LocalStorage.ILocalStorageService localStore
@page "/"

<h1>Your LocalStorage Note</h1>

<textarea @bind="noteContent" />
<br />
<button @onclick="UpdateLocalStorage">Save</button>
<button @onclick="ClearLocalStorage">Clear</button>


@code{
    const string noteKey = "note";
    string noteContent;

    public async void UpdateLocalStorage()
    {
        await localStore.SetItemAsync(noteKey, noteContent);
    }

    public async void ClearLocalStorage()
    {
        noteContent = "";
        await localStore.ClearAsync();
    }

    protected override async Task OnInitializedAsync()
    {
        noteContent = await localStore.GetItemAsync<string>(noteKey);
    }
}

Source

Top comments (3)

Collapse
 
benhayat profile image
Ben Hayat

Man you always have great articles and best presentation.
Thanks Brad!

Collapse
 
bradwellsb profile image
Bradley Wells

Thanks for the encouragement, Ben!

Collapse
 
benhayat profile image
Ben Hayat

I think the "Usefulness" of your articles, is the key. We can immediately use them. A lot of people write stuff that is too long or too specific that is "Useless". :-)