I try to store objects in localStorage
but sometimes I run out of space.
When I try to store an object with localStorage
but don't have enough storage - is there a way to simply delete as much local data as needed to free that space, starting the deletion from the oldest elements?
Is there an API in browsers that lets me do that?
I try to store objects in localStorage
but sometimes I run out of space.
When I try to store an object with localStorage
but don't have enough storage - is there a way to simply delete as much local data as needed to free that space, starting the deletion from the oldest elements?
Is there an API in browsers that lets me do that?
Share Improve this question edited Nov 18, 2013 at 19:31 Benjamin Gruenbaum 277k89 gold badges520 silver badges517 bronze badges asked Nov 18, 2013 at 19:20 cedivadcedivad 2,6546 gold badges34 silver badges41 bronze badges 3- 1 That's not a bad question, but part of the issue with any such API is that I don't think the browsers are consistent about how they respond to the limit. I think some of them throw an error; others will pop up a dialog box asking the user if they'd like to allow more storage. – Katana314 Commented Nov 18, 2013 at 19:26
- 2 Hi, I upvoted and edited your question to ask for a solution rather than an "API". Feel free to revert if you don't like the edit but I think it clarifies things. Nice question by the way. – Benjamin Gruenbaum Commented Nov 18, 2013 at 19:31
- This is not an answer for your questions but I think it could help: stackoverflow./questions/13567509/… – Aguardientico Commented Nov 18, 2013 at 19:39
3 Answers
Reset to default 8Here is a small proof of concept I just whipped up. It assumes an exception is thrown when you try to store items and have no space.
Code is annotated
var Storage = function (iden) { // a storage wrapper object
var storage; // temp storage with variable
if (localStorage[iden]) { // if we already did this, reuse
storage = JSON.parse(localStorage[iden]);
} else {
// the queue is for the item order to find out oldest
storage = {
__queue: [],
items: {}
};
}
function fetch(key) {
console.log(storage);
return storage.items[key];
}
function put(key, value) {
try {
storage.__queue.push(key);
storage.items[key] = value;
localStorage[iden] = JSON.stringify(storage);
} catch (e) { // out of space
if (storage.__queue.length === 0) throw Exception("Too big anyway");
var k = storage.__queue.pop();
delete storage.items[k];
return put(key, value); //try again after deleting
}
}
return {
put: put,
fetch: fetch
};
};
Inspired by @Benjamin's awesome Proof-Of-Concept i used some of his code to e out with another solution, this function will remove the least used value. For instance you have a value like user_id
you read for this value a lot of times, but if this was added first you will lose it when you run out of space.
So this solution will remove the value depending on how much they were used
var Storage = function (iden) { // a storage wrapper object
var storage; // temp storage with variable
if (localStorage[iden]) { // if we already did this, reuse
storage = JSON.parse(localStorage[iden]);
} else {
// frequency map contains which key was hit how many times.
storage = {
__freq: {},
items: {}
};
}
function fetch(key) {
storage.__freq[key]++;
return storage.items[key];
}
function deleteLeastUsed(){
var min_used = '', min_value = 0;
var keys = Object.keys(storage._freq);
// This will be always the first key..awesome ?
min_used = keys.pop();
min_value = storage.__freq[min_used];
keys.forEach(function(key){
if( min_value > storage.__freq[key] ){
min_used = key;
min_value = storage.__freq[min_used];
}
});
delete storage._freq[min_used]
delete storage.items[min_used];
}
function put(key, value) {
try {
// sets frequency to 0 if the key is over-written
// you can use this as `touch` if you don't wanna use a value more times and wan't to free it just set it to its value
storage.__freq[key] = 0;
storage.items[key] = value;
localStorage[iden] = JSON.stringify(storage);
} catch (e) { // out of space
if ( Object.keys(storage.__freq).length === 0)
throw Exception("Too big anyway");
deleteLeastUsed();
return put(key, value); //try again after deleting
}
}
return {
put: put,
fetch: fetch
};
};
Besides if your data-requirements are really high you might wanna consider switching to IndexedDB instead of localStorage. :-)
I've found this in google: https://github./pamelafox/lscache Is a 'memcache' library for localstorage