I know there has been many questions about checking for localStorage but what if someone manually shuts it off in their browser? Here's the code I'm using to check:
localStorage.setItem('mod', 'mod');
if (localStorage.getItem('mod') != null){
alert ('yes');
localStorage.removeItem('mod');
} else {
alert ('no');
}
Simple function and it works. But if I go into my Chrome settings and choose the option "Don't Save Data" (I don't remember exactly what it's called), when I try to run this function I get nothing but Uncaught Error: SecurityError: DOM Exception 18. So is there a way to check if the person has it turned off completely?
UPDATE: This is the second function I tried and I still get no response (alert).
try {
localStorage.setItem('name', 'Hello World!');
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert('Quota exceeded!');
}
}
Use modernizr's approach:
function isLocalStorageAvailable(){
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
if(isLocalStorageAvailable()){
// available
}else{
// unavailable
}
It's not as concise as other methods but that's because it's designed to maximise compatibility.
The original source: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/storage/localstorage.js
Working example: http://jsfiddle.net/6sm54/2/
I'd check that localStorage is defined prior to any action that depends on it:
if (typeof localStorage !== 'undefined') {
var x = localStorage.getItem('mod');
} else {
// localStorage not defined
}
UPDATE:
If you need to validate that the feature is there and that it is also not turned off, you have to use a safer approach. To be perfectly safe:
if (typeof localStorage !== 'undefined') {
try {
localStorage.setItem('feature_test', 'yes');
if (localStorage.getItem('feature_test') === 'yes') {
localStorage.removeItem('feature_test');
// localStorage is enabled
} else {
// localStorage is disabled
}
} catch(e) {
// localStorage is disabled
}
} else {
// localStorage is not available
}
Feature-detecting local storage is tricky. You need to actually reach into it. The reason for this is that Safari has chosen to offer a functional localStorage object when in private mode, but with it's quotum set to zero. This means that although all simple feature detects will pass, any calls to localStorage.setItem will throw an exception.
Mozilla's Developer Network entry on the Web Storage API's has a dedicated section on feature detecting local storage. Here is the method recommended on that page:
function storageAvailable(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return false;
}
}
And here is how you would use it:
if (storageAvailable('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
else {
// Too bad, no localStorage for us
}
If you are using NPM, you can grab storage-available using
npm install -S storage-available
then use the function like so:
if (require('storage-available')('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
Disclaimer: Both the documentation section on MDN and the NPM package were authored by me.
MDN updated the storage detect function. In 2018, it's more reliable:
function storageAvailable() {
try {
var storage = window['localStorage'],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return e instanceof DOMException && (
// everything except Firefox
e.code === 22 ||
// Firefox
e.code === 1014 ||
// test name field too, because code might not be present
// everything except Firefox
e.name === 'QuotaExceededError' ||
// Firefox
e.name === 'NS_ERROR_DOM_QUOTA_REACHED') &&
// acknowledge QuotaExceededError only if there's something already stored
storage && storage.length !== 0;
}
}
Browsers that support localStorage will have a property on the window object named localStorage. However, for various reasons, just asserting that property exists may throw exceptions. If it does exist, that is still no guarantee that localStorage is actually available, as various browsers offer settings that disable localStorage. So a browser may support localStorage, but not make it available to the scripts on the page. One example of that is Safari, which in Private Browsing mode gives us an empty localStorage object with a quota of zero, effectively making it unusable. However, we might still get a legitimate QuotaExceededError, which only means that we've used up all available storage space, but storage is actually available. Our feature detect should take these scenarios into account.
See here for a brief history of feature-detecting localStorage.
With this function you can check if localstorage is available or not, and you keep under control the possible exceptions.
function isLocalStorageAvailable() {
try {
var valueToStore = 'test';
var mykey = 'key';
localStorage.setItem(mykey, valueToStore);
var recoveredValue = localStorage.getItem(mykey);
localStorage.removeItem(mykey);
return recoveredValue === valueToStore;
} catch(e) {
return false;
}
}
It is better to check availability of localStorage in conjunction with cookies, because if cookie is enabled the browser could detect that localStorage is available and type it as object, but provide no possibility to work with it. You use the next function to detect both localStorage and cookies:
const isLocalStorage = () => {
try {
if (typeof localStorage === 'object' && navigator.cookieEnabled) return true
else return false
} catch (e) {
return false
}
}
You can try this method
Anytime validate the content of the localstore
const name = localStorage.getItem('name');
if(name){
console.log('Exists');
}else
{
console.log('Not found');
}
I tried this solution in Chrome, Firefox and Edge and it worked correctly.
if (localStorage.getItem('itemName') === null )
{
// your code here ...
}
if the local variable on localStorage do not exist it will brind false.
You can create a checker function which tries to get a non existing item from the localStorage. When the localStorage is turned on you will normally get null returned. But when the localStorage is turned off an error will be thrown. You don't have to set any item for the checking.
const checkLocalStorage = () => {
try {
localStorage.getItem("x");
return true;
} catch {
return false;
}
}
Modifying Joe's answer to add a getter makes it easier to use. With the below you simply say: if(ls)...
Object.defineProperty(this, "ls", {
get: function () {
var test = 'test';
try {
localStorage.setItem(test, test);
localStorage.removeItem(test);
return true;
} catch(e) {
return false;
}
}
});
Here is an easy check:
if(typeof localStorage === 'undefined'){
Use this to check localStorage is set or not. Its help you to get status of Localstorage.
if( window.localStorage.fullName !== undefined){
//action
}else{
}
Related
I have a very simple function that opens a file as shown in the example on mozilla
// fileHandle is a FileSystemFileHandle
// withWrite is a boolean set to true if write
async function verifyPermission(fileHandle, withWrite) {
const opts = {};
if (withWrite) {
opts.mode = 'readwrite';
}
// Check if we already have permission, if so, return true.
if (await fileHandle.queryPermission(opts) === 'granted') {
return true;
}
// Request permission to the file, if the user grants permission, return true.
if (await fileHandle.requestPermission(opts) === 'granted') {
return true;
}
// The user did not grant permission, return false.
return false;
}
but I keep getting an error saying that file.queryPermission is not a function. Here's my code:
let file = await window.showOpenFilePicker();
console.log(file.queryPermission({ mode: 'readwrite' }));
I've also tried putting the console.log in a .then but had the same result.
If you use Firefox or Safari or older versions of other browsers, then according to MDN and Can I Use queryPermission is not supported in these browsers.
Perhaps you should check your browser's support for this feature.
I've written a webapp that allows you to store the images in the localStorage until you hit save (so it works offline, if signal is poor).
When the localStorage reaches 5MB Google Chrome produces an error in the javascript console log:
Uncaught Error: QUOTA_EXCEEDED_ERR: DOM Exception 22
How do I increase the size of the localStorage quota on Google Chrome?
5MB is a hard limit and that is stupid. IndexedDB gives you ~50MB which is more reasonable. To make it easier to use try Dexie.js https://github.com/dfahlander/Dexie.js
Update:
Dexie.js was actually still an overkill for my simple key-value purposes so I wrote this much simpler script https://github.com/DVLP/localStorageDB
with this you have 50MB and can get and set values like that
// Setting values
ldb.set('nameGoesHere', 'value goes here');
// Getting values - callback is required because the data is being retrieved asynchronously:
ldb.get('nameGoesHere', function (value) {
console.log('And the value is', value);
});
Copy/paste the line below so ldb.set() and ldb.get() from the example above will become available.
!function(){function e(t,o){return n?void(n.transaction("s").objectStore("s").get(t).onsuccess=function(e){var t=e.target.result&&e.target.result.v||null;o(t)}):void setTimeout(function(){e(t,o)},100)}var t=window.indexedDB||window.mozIndexedDB||window.webkitIndexedDB||window.msIndexedDB;if(!t)return void console.error("indexDB not supported");var n,o={k:"",v:""},r=t.open("d2",1);r.onsuccess=function(e){n=this.result},r.onerror=function(e){console.error("indexedDB request error"),console.log(e)},r.onupgradeneeded=function(e){n=null;var t=e.target.result.createObjectStore("s",{keyPath:"k"});t.transaction.oncomplete=function(e){n=e.target.db}},window.ldb={get:e,set:function(e,t){o.k=e,o.v=t,n.transaction("s","readwrite").objectStore("s").put(o)}}}();
You can't, it's hard-wired at 5MB. This is a design decision by the Chrome developers.
In Chrome, the Web SQL db and cache manifest also have low limits by default, but if you package the app for the Chrome App Store you can increase them.
See also Managing HTML5 Offline Storage - Google Chrome.
The quota is for the user to set, how much space he wishes to allow to each website.
Therefore since the purpose is to restrict the web pages, the web pages cannot change the restriction.
If storage is low, you can prompt the user to increase local storage.
To find out if storage is low, you could probe the local storage size by saving an object then deleting it.
You can't but if you save JSON in your localStorage you can use a library to compress data like : https://github.com/k-yak/JJLC
demo : http://k-yak.github.io/JJLC/
Here you can test your program , you should handle also the cases when the cuota is exceed
https://stackoverflow.com/a/5664344/2630686 The above answer is much amazing. I applied it in my project and implement a full solution to request all kinds of resource.
// Firstly reference the above ldb code in the answer I mentioned.
export function get_file({ url, d3, name, enable_request = false }) {
if (name === undefined) { // set saved data name by url parsing alternatively
name = url.split('?')[0].split('/').at(-1).split('.')[0];
}
const html_name = location.href.split('/').at(-1).split('.')[0]
name = `${html_name}_${name}`
let ret = null;
const is_outer = is_outer_net(url); // check outer net url by its start with http or //
// try to access data from local. Return null if not found
if (is_outer && !enable_request) {
if (localStorage[name]) {
ret = new Promise(resolve => resolve(JSON.parse(localStorage[name])));
} else {
ret = new Promise(r => {
ldb.get(name, function (value) {
r(value)
})
});
}
} else {
ret = new Promise(r => r(null))
}
ret.then(data => {
if (data) {
return data
} else {
const method = url.split('.').at(-1)
// d3 method supported
if (d3 && d3[method]) {
ret = d3[method](url)
} else {
if (url.startsWith('~/')) { // local files accessed supported. You need a local service that can return local file data by requested url's address value
url = `http://localhost:8010/get_file?address=${url}`
}
ret = fetch(url).then(data => {
// parse data by requested data type
if (url.endsWith('txt')) {
return data.text()
} else {
return data.json()
}
})
}
ret = ret.then(da => {
data = da
if (is_outer) { // save data to localStorage firstly
localStorage[name] = JSON.stringify(data);
}
}).catch(e => { // save to ldb if 5MB exceed
ldb.set(name, data);
}).finally(_ => {
return data;
});
}
})
return ret;
}
I am making a script in Javascript script that gets a SQL response, then processes it. Basically, I want to check if the username value exists in result[1]. When it checks, it errors out and says that it does not exist. If it does not exist, I want it to return false, not stop the program.
Here is the code:
if (result[1].username != undefined) {
return true;
} else {
return false;
}
I have tried using typeof(result1) == undefined, but it gives me the same error.
First, you have to make sure the result exists, otherwise you'd be indexing into undefined which would crash your application.
Second, you can make that check less verbose with:
return (result[1] && result[1].username)
which will return a falsey value if it doesn't exist, and whatever the username is, if it does.
In case you need an explicit true to be what the function returns, you can coerce it:
return (result[1] && (result[1].username && true))
I would make sure to refactor for readability, but that's the gist.
You could use the in operator. For example:
let trueObj = { username: 'Foo' };
let falseObj = { };
if ('username' in trueObj) {
console.log('username found in trueObj');
} else {
console.log('username not found in trueObj')
}
if ('username' in falseObj) {
console.log('username found in falseObj');
} else {
console.log('username not found in falseObj')
}
First of all please check whether the result itself exists or not and make the corresponding & operator and i think this will definitely help
if (result && result[1] && result[1].username) {
return true;
} else {
return false;
}
But if you don't want to make your code complex then you can try lodash library.
https://lodash.com/
Here's my code:
if(typeof(Storage)!==undefined) {
// Web storage support
if(localStorage.hashes != "") {
var hashes = jQuery.parseJSON(localStorage.hashes);
for (var i = 0; i < hashes.length; i++) {
// Do stuff here
}
}
else {
var hashes = [];
}
}
else {
// No web storage support
}
I don't really know what's going on, but when I try to load the page with this code from a device for the first time, the rest of my code doesn't work the way it should. However, if I comment it out then visit the page for the first time everything works. I can then uncomment it, reload the page, and everything will continue to work. This is really the best I can describe what's happening.
I believe you could have done a little more debugging before posting this.
Have you tried logging/ adding checks (to see where exactly this issue is coming from and what the error is) ?
But since we're here, here are my tips for localStorage :
Use modernizr (http://modernizr.com/)
if(Modernizr.localstorage){ /* Your code */}
Make some generic get and set functions
function get(key) {
if(Modernizr.localstorage) {
if(localStorage[key] != null) {
return localStorage[key];
}
}
return null;
}
function set(key, value) {
if(Modernizr.localstorage) {
localStorage[key] = value;
}
return null;
}
This is pretty rough, you tweek it to make it safer and respond to your needs
Put try/catch inside your get and set functions, you don't want write operations to impact your program
I figured it out! So in the above code I check if they had localStorage available, and if they do, I just assume that they have some hashes stored in there. This obviously creates a problem on their first visit as they wouldn't have any hashes saved yet. So I have to check if they have any, if they do, then do the for loop, otherwise just set it to an empty array. Like so!
if(typeof(Storage) !== "undefined") {
// Web storage support
if(localStorage.hashes != "") {
hashes = JSON.parse(localStorage.getItem("hashes"));
if(hashes) {
for (var i = 0; i < hashes.length; i++) {
// Do Stuff
}
} else {
hashes = [];
}
}
else {
hashes = [];
}
}
else {
// No web storage support
hashes = [];
}
Thanks to jbabey for tips on cleaning up my code some!
Load when the browser is open
Thats my previous question related to this topic.
My problem is that the server api i use has added a new item to the list and as i stated in the previous question im not very skilled with API's or jQuery, therefore i would like to know what can you recomend me to read about this and also pratical solutions. I need to make it so the field that the js uses is only {"name":"Arthas","slug":"arthas","build":"12340","status":1} and not the rest.
Many thanks in advance.
This is the api -> http://api.neverendless-wow.com/server-status
{"servers":[{"name":"Arthas","slug":"arthas","build":"12340","status":1},{"name":"Deathwing","slug":"deathwing","build":"13623","status":1}],"alerts":[]}
This is my current js
function checkStatus()
{
jQuery.getJSON("http://api.neverendless-wow.com/server-status",function(data){
if (data.status == '1') {jQuery('#ServStat').addClass('online').removeClass('offline').attr('label','Online');}
else {jQuery('#ServStat').addClass('offline').removeClass('online').attr('label','Offline');}});
}
checkStatus();
{
setInterval(changeState, 300000)
}
You need to use data as array (data[0]) and hence your code will be as follows:
function checkStatus()
{
jQuery.getJSON("http://api.neverendless-wow.com/server-status",function(data){
if (data.servers[0].status == '1') {
jQuery('#ServStat').addClass('online').removeClass('offline').attr('label','Online');
}
else {
jQuery('#ServStat').addClass('offline').removeClass('online').attr('label','Offline');
}
});
}
checkStatus();
{
setInterval(changeState, 300000)
}
I would probably go with something like this:
// check server status
function checkStatus()
{
$.getJSON(server_url, function(data) {
// reset
var mode = "Offline";
$('.status').removeClass('online').addClass('offline');
// is available?
if (data !== null && data.servers !== null && data.servers[0].status === 1) {
mode = "Online";
$('.status').removeClass('offline').addClass('online');
}
// Extract data from received JSON string is exists
extractData(data);
// set needed attributes
$('.status')
.attr('label', mode)
.text('Servers are ' + mode);
});
}
Live demo available on JsBin