Skip to main contentMAF Configuration Practices

Enabling Persistent Values

About this task

In Graphite applications, there are often scenarios where you need to persist user preferences, form inputs, or application state even when the application is closed and reopened. This guide explains different methods for implementing persistent storage in your Graphite application to enhance user experience by remembering important values across sessions.

Procedure

Step 1: Understand persistence options

Graphite applications offer several methods for persisting data:

  1. localStorage - Browser-based storage that persists until explicitly cleared
  2. sessionStorage - Similar to localStorage but cleared when the browser session ends
  3. Application state - For persisting data within the current application session
  4. Server-side storage - For persisting data across devices and users

Step 2: Choose the appropriate persistence method

Select the appropriate persistence method based on your requirements:

MethodPersistence DurationStorage LimitUse Case
localStorageUntil explicitly cleared~5MBUser preferences, filters, UI settings
sessionStorageUntil browser/tab closes~5MBTemporary session data
Application stateUntil app restartsMemory-boundCurrent session data
Server-sidePermanentDatabase-dependentUser settings across devices

Step 3: Implement persistence using localStorage

The most common method for client-side persistence is using localStorage:

// Save a value to localStorage
function saveValue(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error('Failed to save data to localStorage', error);
}
}

Step 4: Integrate with page initialization

Add code to retrieve and apply saved values when your page initializes:

/**
* Initialize page with persisted values
* @param {Object} page - The page object
* @param {Object} app - The application object
*/
async pageInitialized(page, app) {
this.page = page;
this.app = app;

Step 5: Save values when they change

Implement handlers to save values when they change:

/**
* Save settings when they change
*/
saveSettings() {
const settings = {
selectedTab: this.page.state.selectedTab,
filterValue: this.page.state.filterValue,
showDetails: this.page.state.showDetails
};

Step 6: Connect UI components to persistence logic

Update your page components to trigger the save function when values change:

<tabs selected-tab="{page.state.selectedTab}" on-change="handleTabChange">
<tab id="tab1" label="Details" />
<tab id="tab2" label="Related" />
</tabs>
<input id="filterInput" value="{page.state.filterValue}" on-change="handleFilterChange" />
<checkbox id="showDetailsCheck" checked="{page.state.showDetails}" on-change="handleShowDetailsChange" />

Complete Example

Here’s a complete example showing how to persist filter settings across sessions:

Page XML:

<page id="inventory">
<state name="filterSettings" type="object" default-value="{category: 'all', showInStock: true, sortBy: 'name'}" />
<page-header>
<page-title>Inventory</page-title>
</page-header>
<container>
<box>
<dropdown id="categoryFilter" label="Category" value="{page.state.filterSettings.category}" on-change="handleCategoryChange">

AppCustomizations.js:

import {Application} from '@maximo/maximo-js-api';
class AppCustomizations {
/**
* Initialize page references when the page is initialized
* @param {Object} page - The page object
* @param {Object} app - The application object
*/
async pageInitialized(page, app) {

Best Practices and Considerations

  • Use Namespaced Keys: Prefix localStorage keys with your application name to avoid conflicts with other applications.
  • Handle Storage Errors: Always wrap localStorage operations in try/catch blocks to handle potential errors.
  • Provide Default Values: Always have fallback default values in case stored data is missing or corrupted.
  • Consider Storage Limits: localStorage is limited to about 5MB per domain, so be mindful of how much data you store.
  • Sensitive Data: Never store sensitive information in localStorage as it’s accessible to any JavaScript code running on the same domain.
  • User-Specific Storage: For user-specific settings, consider prefixing keys with the user ID.
  • Versioning: Consider adding a version identifier to your stored data to handle schema changes.
  • Clear Functionality: Provide users with options to reset to defaults or clear their saved preferences.
  • Synchronization: For multi-device scenarios, consider syncing important preferences to the server.
  • Privacy Modes: Be aware that localStorage may not be available or may be cleared in private browsing modes.