Create mobile web applications with HTML5 and local storage

HTML5 is a popular technology since its early days and for a very good reason. It brought desktop application-like capabilities to the web browser — not just on the desktop but also on mobile devices.

In this five-part series, we will take a look at some of the popular features that are part of HTML5. In each part, we will also write some code to showcase these features and see how they work on both desktop and mobile browsers.

One of the most useful new features in HTML5 is the standardization of local storage. Finally, Web developers can stop trying to fit all client-side data into 4 KB Cookies. Now you can store large amounts of data on the client with a simple API. This is a perfect mechanism for caching, so you can dramatically improve the speed of your application — a critical factor for mobile Web applications that rely on much slower connections than their desktop brothers. In this tutorial, you will see how to use local storage, how to debug it, and you will see a variety of ways to use it to improve mobile Web applications.

Prerequisites

In this tutorial, you will develop a web application to showcase the Local Storage API. The code used here covers core web technologies like HTML, Cascading Style Sheets (CSS), and JavaScript. To test the application on desktop and mobile devices, it is recommended that you use the latest web browser versions.

Local storage 101

As websites became more dynamic and data-driven, the need to store data on the client side increased. In many scenarios, web applications need to manage their own state and data, whether to make the app more efficient or because the servers are becoming stateless, and storing client’s data is either insecure or inappropriate. For a long time, HTTP cookies were used for this, but they have their own limitations and may not be the ideal solution.

Fortunately for web developers, the HTML5 specification contains a standard for local storage that is now implemented and used by all popular browsers.

Web Storage API

The Web Storage API offers a way for browsers to store data as key-value pairs. It provides two mechanisms to store data:

  • sessionStorage – Web storage implementation that stores data during a page session. The data is deleted once the session is over, for example when the browser is closed.
  • localStorage – Web storage implementation that is persistent across multiple sessions even when the browser is closed and reopened. The two implementations share the same interface and have their own use case. We will focus on localStorage only.

Let’s look at the Local Storage API.

Listing 1. Local storage

const localStorage = window.localStorage;

localStorage.setItem("key", value);

const value = localStorage.getItem("key");

localStorage.removeItem("key");

localStorage.clear();

const numberOfKeyValuePairsStored = localStorage.length;

const key = localStorage.key(0);

In Listing 1, you can see all the methods and properties exposed by the storage interface. You can access the local storage using window.localStorage. The setItem(key, value) will add the key-value pair to the storage or update the value if the key already exists. The getItem(key) function returns the value associated with the key, or null if the key does not exist. To remove a key-value pair from the storage, you can use the removeItem(key) function; and to remove all key-value pairs, use the clear() function. Finally, you can use the length property to get the total number of key-value pairs stored and use the key(index) function to get the key stored at a specific index. Combining the length and key functions, you can iterate over all of the stored key-value pairs.

There are lots of interesting use cases for local storage. It can be used for caching or saving user preferences. Let’s look at an example that demonstrates how to use local storage to save user preferences.

Example: Store user preferences with local storage

In this example, you will see how to use different methods and properties exposed by the storage API. You can start by saving and retrieving a simple key-value pair in the local storage. Let’s say you want to show how many times a user visited your web page. Store the count in local storage, update the count on each page load event, and then display the count to the user.

It is important to note that the local data storage is not shared across different browsers, so for any use case where you need the data across different browsers or devices, it is recommended to store the data on the server side.

Listing 2. Visit count

<!DOCTYPE html>
<html>
  <head>
    <title>Local Storage</title>
    <script type="text/javascript">

      const localStorage = window.localStorage;

      const initialize = () => {
        if (localStorage) {
          const count = localStorage.getItem("visitCount") || 0;
          const newCount = parseInt(count) + 1;
          localStorage.setItem("visitCount", newCount);
          updateDOM();
        }

      };

      const updateDOM = () => {
        const count = localStorage.getItem("visitCount") || 0;
        document.getElementById(
          "visitCount"
        ).innerHTML = `Visit count ${count}`;
      };
    </script>
  </head>
  <body onload="initialize()">
    <div id="visitCount"></div>
  </body>
</html>

In the code above, you call the initialize function on the loaded page. The local storage is accessible via the global window object using the window.localStorage property. The initialize function first checks if the browser supports local storage. If it does, you will retrieve the current visitCount using the localStorage.getItem function. If the key does not exist, set an initial value of zero for the count variable. The local storage stores the value as a string, so use parseInt to convert the value to integer. Next, increment the count and save the new value using the localStorage.setItem function. Finally, call the updateDOM function, since this retrieves the count value and writes it to the DOM.

If you open your web page and refresh it, the visit count value will update. Even if you close the browser and open it again, the visit count value will increment properly. You can use the browser’s developer tool to inspect this value.

As you have seen, it is easy to use the Local Storage API to store and retrieve a key-value pair. In our example, we stored a simple integer, but you can use the same API to store complex objects if required.

Let’s extend our example to store a JSON object in the local storage.

Listing 3. Store user preferences

<!DOCTYPE html>
<html>
  <head>
    <title>Local Storage</title>
    <script type="text/javascript">
      const localStorage = window.localStorage;

      const initialize = () => {
        if (localStorage) {
          const count = localStorage.getItem("visitCount") || 0;
          const newCount = parseInt(count) + 1;
          localStorage.setItem("visitCount", newCount);
        }
        updateDOM();
      };

      const updateDOM = () => {
        const count = localStorage.getItem("visitCount") || 0;
        const storedPreferences = localStorage.getItem("preference");
        const preference = storedPreferences
          ? JSON.parse(storedPreferences)
          : {};

        document.getElementById(
          "visitCount"
        ).innerHTML = `Visit count ${count}`;
        document.body.style.background = preference.color || "white";
      };

      const setColorPreference = color => {
        const localStorage = window.localStorage;
        const preference = { color }
        localStorage.setItem("preference", JSON.stringify(preference));
        updateDOM();
      };
    </script>
  </head>
  <body onload="initialize()">
    <button type="button" onclick="setColorPreference('red')">Red</button>
    <button type="button" onclick="setColorPreference('green')">Green</button>
    <button type="button" onclick="setColorPreference('blue')">Blue</button>
    <div id="visitCount"></div>
  </body>
</html>

In Listing 3, we made a few changes to the initial code. We added three buttons with labels: Red, Green, and Blue. These buttons call the setColorPreference function on click and pass the color value to this function. This setColorPreference function takes the color as a parameter, creates a preference JSON object, and stores that in the local storage. Here we are using the JSON.stringify(preference) function to convert the JSON object to a string. After storing the user preference in local storage, call the updateDOM function.

You have modified the updateDOM function to get the stored preference from the local store using the localStorage.getItem("preference") function, then converted the string value to preference the JSON object using JSON.parse(storedPreferences). If the value is empty, initialize the preference as an empty object and update the body background based on the color stored in the preference.

Now that you have stored both a simple value and a JSON object to the local storage, let’s explore other functions exposed by the storage API.

Listing 4. Remove count and clear local storage

  <body onload="initialize()">
    <button type="button" onclick="setColorPreference('red')">Red</button>
    <button type="button" onclick="setColorPreference('green')">Green</button>
    <button type="button" onclick="setColorPreference('blue')">Blue</button>
    <div id="visitCount"></div>
    <button type="button" onclick="removeCount()">Remove count</button>
    <button type="button" onclick="clearAll()">Clear all</button>
  </body>

In Listing 4, we added two new buttons to the page: one to remove the visit count and the other to clear all stored key-value pairs. The Remove count button calls the removeCount() function on click, and the Clear all button invokes the clearAll() function. You can see these functions in Listing 5.

Listing 5. Functions to remove count and clear local storage

const removeCount = () => {
    localStorage.removeItem("visitCount");
    updateDOM();
};

const clearAll = () => {
    localStorage.clear();
    updateDOM();
};

In the removeCount function, use the localStorage.removeItem("visitCount") function to remove the visitCount key-value and in the clearAll function use the localStorage.clear() function to clear the local storage. In both the functions, we invoke updateDOM() to update the DOM.

Let’s look at how to retrieve all of the key-value pairs stored in the local storage.

Listing 6. Display all stored key value pairs

<body onload="initialize()">
    <ui id="storedItems"></ui>
    <button type="button" onclick="setColorPreference('red')">Red</button>
    <button type="button" onclick="setColorPreference('green')">Green</button>
    <button type="button" onclick="setColorPreference('blue')">Blue</button>

    <div id="visitCount"></div>
    <button type="button" onclick="removeCount()">Remove count</button>
    <button type="button" onclick="clearAll()">Clear all</button>
</body

First, add an unordered list element <ui id="storedItems"></ui> to your page, as shown in Listing 6. This will be used to display the list of key-value pairs that are stored.

Now add a new function showAllStoredKeyValues, shown in Listing 7. This function first uses console.log to store the number of values in the local storage using the localStorage.length property. You then use localStorage.length to loop through the stored key-value pairs. Use localStorage.key(index) to get the key stored at that index, then use the localStorage.getItem(key) function to get the value. Then add the key-value pair as a list item to the storedItems list.

Listing 7. Function to display all stored key-value pairs

const showAllStoredKeyValues = () => {
    console.log(`we have ${localStorage.length} values`);

    const ul = document.getElementById("storedItems");
    ul.innerHTML = "";

    for (let index = 0; index < localStorage.length; index++) {
      const key = localStorage.key(index);
      var li = document.createElement("li");
      li.appendChild(
        document.createTextNode(`${key} = ${localStorage.getItem(key)}`)
      );
      ul.appendChild(li);
    }
 };

 const updateDOM = () => {
    const count = localStorage.getItem("visitCount") || 0;
    const storedPreferences = localStorage.getItem("preference");
    const preference = storedPreferences
      ? JSON.parse(storedPreferences)
      : {};

    document.getElementById(
      "visitCount"
    ).innerHTML = `Visit count ${count}`;
    document.body.style.background = preference.color || "white";

    showAllStoredKeyValues();
};

Finally, update the updateDOM function to call the showAllStoredKeyValues function.

With this simple example, you have seen how to use all of the functions and properties exposed by the storage API.

Summary

In the example covered here, you have seen how to use the storage API to save user preferences. You can use the same APIs and concepts to build innovative web solutions. Instead of using cookies or other proprietary solutions to store data on the client side, you can now use a standard way that will work across most popular browsers, on both the desktop and mobile. You can use local storage for the local caching of data to improve the performance of your app and provide a better experience to your users.

Acknowledgements

This article was originally written by Michael Galpin and published on May 25, 2010.