Hone logo
Hone
Problems

Implementing Pinia Persistence with LocalStorage

Pinia is a fantastic state management library for Vue.js, but by default, its state is lost when the browser is refreshed or the application is closed. This challenge tasks you with adding persistence to a Pinia store, ensuring that the store's data is saved to and retrieved from localStorage so it survives browser refreshes and application restarts. This is crucial for creating a better user experience, especially in applications where data loss would be disruptive.

Problem Description

You need to create a Pinia store that persists its state to localStorage. The store should automatically save its state to localStorage whenever the state changes and load the state from localStorage when the store is initialized. The store should handle cases where localStorage is unavailable (e.g., in private browsing mode) gracefully, defaulting to an empty state in such scenarios.

What needs to be achieved:

  • Create a Pinia store named UserStore.
  • The UserStore should have the following state properties:
    • name: A string representing the user's name (default: "").
    • age: A number representing the user's age (default: 0).
    • loggedIn: A boolean indicating whether the user is logged in (default: false).
  • Implement persistence using localStorage. The store's state should be saved to localStorage under the key "userStore".
  • When the store is initialized, it should attempt to load the state from localStorage. If localStorage is unavailable or the key "userStore" doesn't exist, the store should initialize with its default state.
  • The store should have actions to update the name, age, and loggedIn properties.

Key Requirements:

  • The persistence logic should be encapsulated within the UserStore.
  • The store should handle potential errors when accessing localStorage.
  • The store should not throw errors if localStorage is unavailable.
  • The store should be reactive, meaning changes to the state should trigger updates in the UI.

Expected Behavior:

  1. On initial load, if "userStore" exists in localStorage, the store should be initialized with the data from localStorage.
  2. If "userStore" does not exist in localStorage, the store should be initialized with its default values.
  3. Whenever any of the state properties (name, age, loggedIn) are modified through actions, the updated state should be immediately saved to localStorage.
  4. On subsequent page loads, the store should be initialized with the data from localStorage (if available).

Edge Cases to Consider:

  • localStorage is unavailable (e.g., private browsing mode).
  • The data in localStorage is corrupted or invalid (e.g., a string instead of an object). The store should gracefully handle this and initialize with default values.
  • The localStorage key "userStore" exists but contains empty data.

Examples

Example 1:

Input: Initial load, localStorage is empty.
Output: UserStore.name = "", UserStore.age = 0, UserStore.loggedIn = false
Explanation: The store initializes with default values because there's no existing data in localStorage.

Example 2:

Input: UserStore.name = "Alice", UserStore.age = 30, UserStore.loggedIn = true;  Refresh the page.
Output: UserStore.name = "Alice", UserStore.age = 30, UserStore.loggedIn = true
Explanation: The store loads the saved state from localStorage after the refresh.

Example 3:

Input: localStorage is unavailable (e.g., private browsing).
Output: UserStore.name = "", UserStore.age = 0, UserStore.loggedIn = false
Explanation: The store initializes with default values because localStorage is not accessible.

Constraints

  • The solution must be written in TypeScript.
  • The solution must use Pinia version 2 or higher.
  • The solution must use localStorage for persistence.
  • The solution should be reasonably performant; avoid unnecessary operations that could impact the user experience. (e.g., don't stringify/parse the entire store state on every change if only one property changed).
  • The solution should be well-structured and easy to understand.

Notes

  • Consider using JSON.stringify and JSON.parse to serialize and deserialize the store's state for localStorage.
  • Think about how to handle potential errors when accessing localStorage. Use try/catch blocks to prevent the application from crashing.
  • You can use the watch function in Pinia to detect state changes and trigger the persistence logic. However, be mindful of performance implications if you're watching multiple properties. Consider debouncing the save operation.
  • Focus on creating a robust and reliable persistence mechanism that can handle various scenarios.
  • Remember to test your solution thoroughly, including edge cases.
Loading editor...
typescript