Cordova - Storage
Cordova - Client-Side Storage Options
Section titled “Cordova - Client-Side Storage Options”Cordova applications can leverage various client-side storage mechanisms to store data locally on the device. This enables offline functionality, improves performance by caching data, and allows for saving user preferences. This tutorial focuses on localStorage, a simple key-value store, and briefly mentions other options.
Using localStorage
Section titled “Using localStorage”localStorage is part of the Web Storage API, available in all modern web views. It allows you to store data as key-value pairs, where both keys and values are strings.
Step 1 - Prepare the UI
Section titled “Step 1 - Prepare the UI”In www/index.html, create buttons to interact with localStorage and a div to display stored data or messages.
<body> <h1>localStorage Demo</h1> <input type="text" id="dataKey" placeholder="Enter Key (e.g., userTheme)"> <input type="text" id="dataValue" placeholder="Enter Value (e.g., dark)"> <br><br> <button id="setItemBtn">SET Item</button> <button id="getItemBtn">GET Item by Key</button> <button id="removeItemBtn">REMOVE Item by Key</button> <button id="listAllBtn">LIST All Items</button> <button id="clearAllBtn">CLEAR All Storage</button>
<div id="storageOutput" style="margin-top: 20px; border: 1px solid #ccc; padding: 10px;"> Storage data will appear here... </div>
<script src="cordova.js"></script> <script src="js/index.js"></script></body>Step 2 - Implement JavaScript Logic
Section titled “Step 2 - Implement JavaScript Logic”In www/js/index.js, access localStorage directly. It’s available immediately and doesn’t require deviceready (though your app logic might).
// No 'deviceready' needed for localStorage itself, but good practice for app structure.document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() { console.log('Device is ready. localStorage is available.');
const keyInput = document.getElementById('dataKey'); const valueInput = document.getElementById('dataValue'); const outputDiv = document.getElementById('storageOutput');
document.getElementById('setItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); const value = valueInput.value.trim(); if (key && value) { // For non-string data, serialize to JSON // For this example, we assume simple strings or let users manage JSON manually. localStorage.setItem(key, value); outputDiv.textContent = `Item set: ${key} = ${value}`; console.log(`localStorage.setItem: ${key} = ${value}`); } else { outputDiv.textContent = 'Please provide both key and value.'; } });
document.getElementById('getItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); if (key) { const value = localStorage.getItem(key); if (value !== null) { outputDiv.textContent = `Item found: ${key} = ${value}`; console.log(`localStorage.getItem(${key}): ${value}`); } else { outputDiv.textContent = `Item with key '${key}' not found.`; console.log(`localStorage.getItem(${key}): null`); } } else { outputDiv.textContent = 'Please provide a key to retrieve.'; } });
document.getElementById('removeItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); if (key) { localStorage.removeItem(key); outputDiv.textContent = `Item with key '${key}' removed (if it existed).`; console.log(`localStorage.removeItem: ${key}`); } else { outputDiv.textContent = 'Please provide a key to remove.'; } });
document.getElementById('listAllBtn').addEventListener('click', () => { outputDiv.innerHTML = '<h3>All localStorage Items:</h3>'; if (localStorage.length === 0) { outputDiv.innerHTML += '<p>localStorage is empty.</p>'; return; } const ul = document.createElement('ul'); for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); const value = localStorage.getItem(key); const li = document.createElement('li'); li.textContent = `${key}: ${value}`; ul.appendChild(li); } outputDiv.appendChild(ul); console.log('localStorage contents:', localStorage); });
document.getElementById('clearAllBtn').addEventListener('click', () => { localStorage.clear(); outputDiv.textContent = 'All items cleared from localStorage.'; console.log('localStorage.clear() executed.'); });}localStorage API Methods
Section titled “localStorage API Methods”| Method | Description |
|---|---|
setItem(key, value) | Adds or updates a key-value pair. Both key and value are converted to strings. |
getItem(key) | Retrieves the value associated with the key. Returns null if the key doesn’t exist. |
removeItem(key) | Removes the key-value pair associated with the key. |
key(index) | Returns the name of the key at the given integer index. The order of keys is not guaranteed and can vary between browser engines. Do not rely on this order. |
length (property) | Returns the number of key-value pairs stored. |
clear() | Removes all key-value pairs. |
Important Notes on localStorage
Section titled “Important Notes on localStorage”- String Data Only:
localStoragestores all data as strings. If you need to store objects or arrays, you must serialize them to JSON strings (e.g., usingJSON.stringify()) before saving and parse them (usingJSON.parse()) after retrieving. - Synchronous:
localStorageoperations are synchronous, meaning they block the main thread. For complex data or frequent operations, this can impact performance. Consider asynchronous alternatives for more demanding scenarios. - Storage Limits:
localStoragehas a storage limit, typically around 5-10MB per origin, though this can vary by browser/WebView. - Security: Data in
localStorageis not encrypted and can be accessed by any script running on the same origin. Do not store sensitive information like passwords or tokens directly. - Persistence: Data in
localStoragepersists until explicitly cleared by the app or the user (e.g., by clearing browser data). It is not cleared if the app is updated. - Order of Keys: As mentioned,
localStorage.key(index)does not guarantee a specific order. If order is important, manage it yourself (e.g., store an array of keys).
Other Storage Options in Cordova
Section titled “Other Storage Options in Cordova”While localStorage is convenient for simple data, Cordova apps can also use more advanced storage solutions:
sessionStorage: Similar tolocalStoragebut data is cleared when the session ends (e.g., app is closed). Not typically used for persistent data in mobile apps.- IndexedDB: A more powerful, asynchronous, transactional NoSQL database built into modern browsers/WebViews. Suitable for storing larger amounts of structured data. Can be complex to use directly; libraries like PouchDB or Dexie.js can simplify its usage.
- WebSQL (Deprecated): An older API providing SQL database access. It’s deprecated and not recommended for new projects. Support is inconsistent.
- Cordova Plugins for Storage:
-
cordova-sqlite-storage: Provides access to a native SQLite database. Excellent for relational data, large datasets, and complex queries. Operations are asynchronous.
-
cordova-plugin-nativestorage: Offers a native, asynchronous key-value store, potentially more performant or robust thanlocalStoragefor some use cases, especially on certain platforms. Useful for preferences and small data.
-
cordova-plugin-file: For storing data as files in the device’s file system. Suitable for binary data, large blobs, or user-generated files.
Choosing the Right Storage
Section titled “Choosing the Right Storage”The best storage choice depends on your app’s needs:
- Simple key-value pairs, small data, non-sensitive user preferences:
localStoragecan be sufficient. - Larger structured data, offline capabilities, complex queries: IndexedDB (with a helper library) or
cordova-sqlite-storage. - Storing files (images, documents, etc.):
cordova-plugin-file. - Improved asynchronous key-value storage:
cordova-plugin-nativestorage.
For more advanced storage needs, explore the plugins mentioned and their documentation. Understanding the trade-offs between simplicity, performance, storage capacity, and data structure capabilities is key.