JSON and Local Storage
JSON (JavaScript Object Notation) is a lightweight data format. Local Storage provides persistent client-side storage in the browser.
JSON (JavaScript Object Notation)
JSON.stringify()
javascript// Convert JavaScript object to JSON string const user = { name: 'Alice', age: 25, hobbies: ['reading', 'coding'], active: true }; const jsonString = JSON.stringify(user); console.log(jsonString); // '{"name":"Alice","age":25,"hobbies":["reading","coding"],"active":true}' // Pretty formatting with indentation const formatted = JSON.stringify(user, null, 2); console.log(formatted); /* { "name": "Alice", "age": 25, "hobbies": [ "reading", "coding" ], "active": true } */ // Using replacer function const filtered = JSON.stringify(user, ['name', 'age']); console.log(filtered); // '{"name":"Alice","age":25}'
JSON.parse()
javascript// Convert JSON string to JavaScript object const jsonData = '{"name":"Bob","age":30,"city":"New York"}'; const user = JSON.parse(jsonData); console.log(user.name); // 'Bob' console.log(user.age); // 30 // Handle parsing errors function safeJsonParse(jsonString) { try { return JSON.parse(jsonString); } catch (error) { console.error('Invalid JSON:', error.message); return null; } } const validJson = '{"valid": true}'; const invalidJson = '{invalid json}'; console.log(safeJsonParse(validJson)); // { valid: true } console.log(safeJsonParse(invalidJson)); // null
JSON Limitations
javascriptconst complexObject = { name: 'Test', date: new Date(), func: function() { return 'hello'; }, undefined: undefined, symbol: Symbol('test'), regex: /test/g }; const jsonString = JSON.stringify(complexObject); console.log(jsonString); // '{"name":"Test","date":"2024-01-15T10:30:00.000Z","regex":{}}' // Note: function, undefined, and symbol are omitted // Date becomes string, RegExp becomes empty object
Local Storage
Storing Data
javascript// Store simple values localStorage.setItem('username', 'john_doe'); localStorage.setItem('theme', 'dark'); localStorage.setItem('fontSize', '16'); // Store objects (must convert to JSON) const userSettings = { language: 'en', notifications: true, autoSave: false }; localStorage.setItem('userSettings', JSON.stringify(userSettings)); // Store arrays const favoriteColors = ['blue', 'green', 'purple']; localStorage.setItem('favoriteColors', JSON.stringify(favoriteColors));
Retrieving Data
javascript// Get simple values const username = localStorage.getItem('username'); console.log(username); // 'john_doe' const theme = localStorage.getItem('theme'); console.log(theme); // 'dark' // Get objects (parse from JSON) const settingsJson = localStorage.getItem('userSettings'); if (settingsJson) { const settings = JSON.parse(settingsJson); console.log(settings.language); // 'en' console.log(settings.notifications); // true } // Get with default value function getStorageItem(key, defaultValue) { const item = localStorage.getItem(key); return item ? JSON.parse(item) : defaultValue; } const preferences = getStorageItem('preferences', { theme: 'light' });
Managing Storage
javascript// Remove specific item localStorage.removeItem('username'); // Clear all storage localStorage.clear(); // Check if item exists if (localStorage.getItem('theme')) { console.log('Theme setting found'); } // Get all keys const keys = Object.keys(localStorage); console.log('Stored keys:', keys); // Get storage size (approximate) let totalSize = 0; for (let key in localStorage) { if (localStorage.hasOwnProperty(key)) { totalSize += localStorage[key].length + key.length; } } console.log('Approximate storage size:', totalSize, 'characters');
Practical Examples
User Preferences Manager
javascriptclass PreferencesManager { constructor() { this.storageKey = 'userPreferences'; this.defaults = { theme: 'light', language: 'en', fontSize: 'medium', notifications: true }; } load() { try { const stored = localStorage.getItem(this.storageKey); return stored ? { ...this.defaults, ...JSON.parse(stored) } : this.defaults; } catch (error) { console.error('Error loading preferences:', error); return this.defaults; } } save(preferences) { try { localStorage.setItem(this.storageKey, JSON.stringify(preferences)); return true; } catch (error) { console.error('Error saving preferences:', error); return false; } } update(key, value) { const current = this.load(); current[key] = value; return this.save(current); } reset() { localStorage.removeItem(this.storageKey); } } // Usage const prefs = new PreferencesManager(); const userPrefs = prefs.load(); console.log(userPrefs); prefs.update('theme', 'dark'); prefs.update('fontSize', 'large');
Shopping Cart Storage
javascriptclass ShoppingCart { constructor() { this.storageKey = 'shoppingCart'; this.items = this.loadCart(); } loadCart() { try { const stored = localStorage.getItem(this.storageKey); return stored ? JSON.parse(stored) : []; } catch (error) { console.error('Error loading cart:', error); return []; } } saveCart() { try { localStorage.setItem(this.storageKey, JSON.stringify(this.items)); } catch (error) { console.error('Error saving cart:', error); } } addItem(product, quantity = 1) { const existingItem = this.items.find(item => item.id === product.id); if (existingItem) { existingItem.quantity += quantity; } else { this.items.push({ ...product, quantity }); } this.saveCart(); } removeItem(productId) { this.items = this.items.filter(item => item.id !== productId); this.saveCart(); } updateQuantity(productId, quantity) { const item = this.items.find(item => item.id === productId); if (item) { item.quantity = quantity; this.saveCart(); } } getTotal() { return this.items.reduce((total, item) => total + (item.price * item.quantity), 0); } clear() { this.items = []; localStorage.removeItem(this.storageKey); } } // Usage const cart = new ShoppingCart(); cart.addItem({ id: 1, name: 'Laptop', price: 999 }, 1); cart.addItem({ id: 2, name: 'Mouse', price: 25 }, 2); console.log('Cart total:', cart.getTotal());
Form Data Persistence
javascriptfunction saveFormData(formId) { const form = document.getElementById(formId); const formData = new FormData(form); const data = {}; for (let [key, value] of formData.entries()) { data[key] = value; } localStorage.setItem(`form_${formId}`, JSON.stringify(data)); } function loadFormData(formId) { const stored = localStorage.getItem(`form_${formId}`); if (!stored) return; try { const data = JSON.parse(stored); const form = document.getElementById(formId); Object.entries(data).forEach(([key, value]) => { const field = form.querySelector(`[name="${key}"]`); if (field) { field.value = value; } }); } catch (error) { console.error('Error loading form data:', error); } } function clearFormData(formId) { localStorage.removeItem(`form_${formId}`); } // Auto-save form data function setupAutoSave(formId, delay = 1000) { const form = document.getElementById(formId); let timeout; form.addEventListener('input', () => { clearTimeout(timeout); timeout = setTimeout(() => saveFormData(formId), delay); }); }
Storage Limitations and Best Practices
javascript// Check storage availability function isStorageAvailable() { try { const test = '__storage_test__'; localStorage.setItem(test, test); localStorage.removeItem(test); return true; } catch (error) { return false; } } // Handle storage quota exceeded function safeSetItem(key, value) { try { localStorage.setItem(key, value); return true; } catch (error) { if (error.name === 'QuotaExceededError') { console.warn('Storage quota exceeded'); // Could implement cleanup strategy here } return false; } } // Storage size estimation function getStorageSize() { let total = 0; for (let key in localStorage) { if (localStorage.hasOwnProperty(key)) { total += localStorage[key].length + key.length; } } return total; } console.log('Storage size:', getStorageSize(), 'characters'); console.log('Storage available:', isStorageAvailable());