Skip to content

Instantly share code, notes, and snippets.

@ghengeveld
Created April 2, 2020 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghengeveld/90067a413411213adb4a6fd0451b758d to your computer and use it in GitHub Desktop.
Save ghengeveld/90067a413411213adb4a6fd0451b758d to your computer and use it in GitHub Desktop.
Safe localStorage & sessionStorage with JSON support
const storage = type => ({
/**
* Asserts that sessionStorage or localStorage is available.
*
* Returns true even on quota exceeded error, so we won't silently ignore when we're using too much
* space, unless we haven't stored anything yet which will happen when the browser has set a very
* strict size limit (i.e. Safari Private Browsing sets quota to 0).
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
*/
isAvailable() {
let storage
try {
const x = "__storage_test__"
storage = window[type]
storage.setItem(x, x)
storage.removeItem(x)
return true
} catch (e) {
return (
e instanceof window.DOMException &&
(e.code === 22 ||
e.code === 1014 ||
e.name === "QuotaExceededError" ||
e.name === "NS_ERROR_DOM_QUOTA_REACHED") &&
(storage && storage.length !== 0)
)
}
},
/**
* Retrieve an item from localStorage.
*
* @param {string} key Item key
* @return {string} The item value, or undefined if not found
*/
getItem(key) {
try {
return window[type] && window[type].getItem(key)
} catch (e) {
console.error(e)
}
},
/**
* Store an item in localStorage, checking for availability.
*
* @param {string} key Item key
* @param {string} value Item value
* @return {boolean} true if succeeded, false otherwise
*/
setItem(key, value) {
try {
this.isAvailable() && window[type].setItem(key, value)
return true
} catch (e) {
console.error(e)
return false
}
},
/**
* Remove an item from localStorage.
*
* @param {string} key Item key
* @return {void}
*/
removeItem(key) {
try {
return window[type] && window[type].removeItem(key)
} catch (e) {
console.error(e)
}
},
/**
* Retrieve an object from localStorage, using JSON deserialization.
*
* @param {string} key Item key
* @return {string|array|object}
*/
getJson(key) {
try {
const item = this.getItem(key)
return item && JSON.parse(item)
} catch (e) {
console.error(e)
}
},
/**
* Store an object in localStorage using JSON serialization.
*
* @param {any} key Item key
* @param {string|array|object} data Item value, must be JSON-serializable
* @return {boolean} true if succeeded, false otherwise
*/
setJson(key, data) {
try {
return this.setItem(key, JSON.stringify(data))
} catch (e) {
console.error(e)
return false
}
},
})
export const localStorage = storage("localStorage")
export const sessionStorage = storage("sessionStorage")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment