localStorage, better handling when memory fills up - javascript

I am writing an application that derives a lot of image data, and doing that takes qutie some time, and during that time the user is waiting.
When I have derived the data I would like to store it in case the user wants to see it again anytime soon. I have been going through some local storage methods in html5 and the most promising for my case seems to be localStorage.
A downside to localstorage is that it tends to not allow that much data to be stored, 5Mb in most cases, and my thoughts are to every time i derive some data, to store it in localStorage. The problem arises when those poor little 5MB get filled up, and then I would like to delete the oldest element from the memory, bu there seems to be no easy way of doing that as everything is just stored in key-value pairs.
So I'm not quite sure how to proceed with using localStorage in this case.
Is there any module or something that can make using localStorage in the manner described above easier?

You can use
1) IndexedDB to store huge data but it will only work in latest browser except Opera mini.
2) OR, store your data in memory and later on to localstorage or vice versa.
3) You can always put your time tag with each key you are storing. you can traverse through keys having specific format to get the oldest key in store and you can delete it easily.
4) you can also put your time stamp in data with your image data, in this case you will not have to extract all keys but complete data objects from the store.
I would suggest you IndexedDB option to overcome your size limitaions.
Hope this will help.

In the end i used this module: https://gist.github.com/ragnar-johannsson/10509331.
Using it the oldest values get deleted if there isnt enough memory to add a new one.

Related

Easiest way to store little information

I am quite new to coding so apologies if I'm asking an obvious question. I have managed to create a little web app in html/JavaScript that takes user input and transforms it and dumps it into a variable that I am interested in. All in all, all the information that I want to extract is in the form of an array comprising of 20 integers in the JavaScript code.
What I want to do now is find how to store that information so when somebody fills out the inputs and submits the form - I can have access to it. I have looked around the web and the common suggestion seems to be SQL database. I was just wondering if there is a simpler way of going about it, especially considering the tiny amount of information I need to store?
Well, if you just want to store the data on the website itself for each individual client, localStorage is the way to go. In other words, if you want to just store a bit of data for later, localStorage allows you to store data that is accessible the next time the user loads the page. This data can't be shared with other users, but if your app doesn't need too much security, or data sharing between users, localStorage is the way to go. However, the user can control what's in localStorage, so you need to make sure that you don't store anything sensitive there. In addition, you won't be able to see the data actually stored in localStorage on your website as the developer. All your handling has to be done on the client side. Every browser supports it, and it's really simple to use.
First off, you can set a value in localStorage like this:
localStorage.foo = "bar";
Then, you can get a value from localStorage like this:
localStorage.foo; //Returns "bar"
The only problem is, localStorage values can only be stored as strings.
So, in order to store an array (like you wanted to), you can do:
localStorage.arr = JSON.stringify([1, 2, 3]);
This turns the array into a string.
Then, to get the array from localStorage:
JSON.parse(localStorage.arr)
That's pretty much all you need to know for what you are describing.
If you want the full story on localStorage, visit: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
I hope this answer helped.

JS "upgrade" patterns

Are there any patterns for cases when something (in my case it's a filters) is stored on client (e.g. localStorage) and you need to run a script once per user/version to migrate data you store. For example, initially there is a filter saved in localStorage with a key myFilter after some time you decide that you need to separate filters per environment, so you need separate dev-myFilter, train-myFilter, etc. You update your code to work with environment-dependant filters, but there are users who have old myFilter and you want with next deployed version to run script which will update the key of saved filter if there is one.
Question is - what are patterns/best practices for that?
I don't know about "best practices", but the obvious technical solution, just like with any API or storage format, is to store a version number alongside the data. If you didn't do so from the start, assume version == 1 when absent.
You may be able to avoid this if the data structure is so unique between versions that the version can be determined simply by examining it.
Either way, you simply perform the translation whenever you spot that the user's data is in the old format.
The downside of this is that you have to keep checking; for a web application this is unlikely to be a bottleneck, but if you can make your data forward-compatible from the outset then you may save a bit of processing time on each request. But for the data to be useful you've got to read it anyway, so a little branching for as long as you wish to maintain backward-compatibility is, again, unlikely to be a big problem.

How to save progress in an html game

I want to know how I can save the progress a player has made in a game that I am making. Could I do this through cookies or how else can I save to the players computer? Thanks for all of the help!
You have pretty much two options for saving localy using Javascript, which are cookies and localStorage.
With Cookies:
The document.cookie property is used for setting, reading, altering and deleting browser cookies.
To set a cookie, document.cookie="cookiename=Foo Bar";, alternatively like so if you want an expiry date: document.cookie="cookiename=Foo Bar; expires=Mon, 18 Jan 2016 12:00:00 UTC";
To read a cookie, just the code document.cookie will return all of your site's cookies on that page. It doesn't put them in an array, but instead a single string in the format of cookiename=foobar; nextcookiename=foobar;, etc. You can turn this into an array easily using document.cookie.split("; ");
To alter a cookie, simply set it again as described above, as that will overwrite it
To delete a cookie, set it again with an expiry date in the past. This will overwrite it, and then it will expire, deleting it.
With localStorage:
The new HTML5 localStorage Object is another way to store data locally:
To set an item in localStorage, use localStorage.setItem('itemname','contents');
To read an item, it's localStorage.getItem('itemname');. You can check if an item exists using "truthy" values (i.e. if(localStorage.getItem('itemname')))
You can alter a localStorage item using localStorage.setItem as described above.
You can delete a localStorage item using localStorage.removeItem('itemname').
Which should I use?
Cookies are supported in just about any browser that you can think of, however they expire (they get deleted after a set amount of time) and also can be disabled by users. Personally, I also find document.cookie a clunky interface.
localStorage on the other hand cannot be easily disabled by the user, and provides a more accessible interface for the programmer. As far as I'm aware, there is no expiration for localStorage. Since localStorage is new with HTML5, it may not work in some older browsers (however it's got great coverage on new browsers, see http://caniuse.com/#feat=namevalue-storage). Note that there is a limit for storing data on your entire site, not just for one item.
In the end, it's up to you. Pick the one you think is going to work best for your game - if you're already using other HTML5 content (such as <canvas>) then there's no harm in localStorage and you'll be using a more reliable storage method. However, if you're happy with cookies then they are a perfectly viable option used by thousands of extremely popular sites - some even use both! One advantage to cookies is that they can be accessed by your web server, whereas localStorage cannot be.
Either way, you'll need to check out the cookie law, which effects all types of storage on the user's computers by a web app.
The hardest part of this problem is not finding a way to persist the data, but instead designing your game in such a way that you have a "game state" that can be serialized for saving between sessions.
Imagine you are writing a game with a player and a score and you're using two variables to represent them.
var player = { x: 4, y: 3 };
var score = 10;
It's relatively easy to save these variables with localStorage.
function save() {
localStorage.setItem('player', JSON.stringify(player));
localStorage.setItem('score', JSON.stringify(score));
}
function load() {
player = JSON.parse(localStorage.getItem('player'));
score = JSON.parse(localStorage.getItem('score'));
}
We have to remember to convert them to JSON before storing, because localStorage can only accept string values.
Each time you make your game state more complex you have to come back and edit both of these functions. It also has the undesirable effect of forcing the game state to be represented with global variables.
The alternative is to represent the entire state with one atom — in this case a Javascript object.
var state = {
player: { x: 4, y: 3 },
score: 10
};
Now you can write much more intuitive save and load functions.
var SAVE_KEY = 'save';
function save(state) {
localStorage.setItem(SAVE_KEY, JSON.stringify(state));
}
function load() {
return JSON.parse(localStorage.getItem(SAVE_KEY));
}
This pattern allows you to keep state as a local variable and use these functions to work with it.
var state = load();
state.score += 10;
save(state);
In actuality it's quite easy to switch between storage mechanisms, but localStorage is probably the easiest to get started with.
For a small game you'll probably never reach the 5MB size limit and if you do, then you'll also find that the synchronous JSON.stringify and localStorage.setItem operations are causing your game to freeze for a few seconds whenever you save.
If this becomes a problem, then you should probably look for a more efficient way to structure your state and maybe consider designing an incremental saving technique, targeting IndexedDB rather than localStorage.
It really depends on what your looking for.
Cookies are a great way to store data but can be edited by the client and some browsers have cookies turned of.
Web storage has its goods and bads too. If your game has to write masses of data and has lots of players it will quickly use up your bandwidth and may also take time to transfer depending on the clients connection. The upside is that it is fully controllable by you. Once the data has been sent, it can not be edited by the client.
Javascript has some great file I/O utils to help you on the way. Here is a great tutorial: https://developer.mozilla.org/en-US/Add-ons/Code_snippets/File_I_O
If you decide to go with cookies it can be harder or easier depending on your skill. Again, here is a great tutorial: http://www.w3schools.com/js/js_cookies.asp.
Hope this helps!!!
Edit---
When I mentioned client I was really meaning to say player :D

localStorage not storing persistently between two pages

I'm developing an application and, at certain point, I need to store information that requires to be persistent between multiple pages, more probably, it will only be 2 pages.
The amount of information varies between just a few bytes and about 15KB (It will never be more than 20KB, ever). I can't really properly predict beforehand how much it will be.
For that I decided to use localStorage.
For now I'm only working on localhost:8080.
The pages, for now have only generic names: pageA.php and pageB.php.
The pages reside on the root of the domain. I.e.
http://localhost:8080/pageA.php
http://localhost:8080/pageB.php
...
At certain times, I store data on localStorage, on pageA.php (I do use the setItem() method).
When the user moves to pageB.php, pageB.php's script then tries to get the data that was stored in pageA.php.
The problem is that getItem() always returns null on pageB.php
I did check the keys I'm using and they are the same, so there should be no problems there.
I've checked, data stored is persisting between page loads as long as the url does not change.
What am I doing wrong here?
Note: tested only on Firefox 19 and on chrome 24
The problem here was that the editor I was using had been changed such that it was searching with case sensitivity.
When I changed the string i was using for the key, the replacer didn't match all the strings due to case sensivity.
I solved it by searching and adapting each key such that all keys had the same characters with the same case, not the same characters regardless of case.
In the in the end, it was just lack of attention. As expected, strings in javascript are case sensitive and that also applies to the key for localStorage and sessionStorage

Is it possible to serialize Javascript object variable and store into cookies?

Is it possible to serialize Javascript object variable and store into cookies? Or is there other way to accomplish the same thing?
If these objects aren't sensitive (I.e., you don't care if your users modify them), then serializing them into cookies is fine, provided that your objects are small enough not to cause issue.
If your cookies ARE sensitive (you need to depend on them to a level of integrity) or you have large structures, then why not consider storing these serialized objects in a persistant session that is stored on your server. You can then use the cookies as a key or ID to know which session to restore when your visitor returns. In this manner, the size of your serialized objects and whether they might 'fit' in a cookie is no longer relevant.
Another possibility if you not fussy about users modifying things, but do require ample space, (although may not work for all browsers,) is to create a HTML5 'local database' or client-side storage. In this manner, you are both eliminating your concern about the size of the cookies as well as the growing size of your own server-side database. This is probably the best option for sites where you want to store a lot of data per user, but you're not sure if they'll ever come back again. You can always resort to server-side storage (see above) for older browsers.
Here's a particularly good tutorial for getting started with HTML5 local databases: http://blog.darkcrimson.com/2010/05/local-databases/
I hope this is helpful & good luck!
I don't see why not if it fit into length limit of the cookie. I would convert serialized object into say Base64 though.
What problem you're solving?
Yes, it's possible, if the resulting string does'nt exceed the limit of the cookie-size(4KB)

Categories