Introduction

I’ve recently had the need to store information using HTML5’s local storage API.  To my surprise the API itself is geared toward only letting you store strings.  That being said I needed to store and retrieve information in a way that would make it easy to retain types as well as store complete objects.  The following is the approach I used which should help those of you unfamiliar with HTML5 local storage get up to speed on how to use it, as well as introduce a possibly not so obvious way to store complete object information as well as retain basic types.

Basic Storage

Basic storage of information is simple.

localStorage["mykey"] = "myvalue"

Retrieval is just as easy.

var myvalue = localStorage["mykey"];

Type Storage

But what about actual types? Hmmm….

localStorage["mykey"] = 42;
var myvalue = localStorage["mykey"]; //returns the string "42"

//wait a minute...

localStorage["mykey"] = {};
var myvalue = localStorage["mykey"]; //returns the string "[object Object]"

Well crap! I’ve lost my input type and retrieved a string on the other side.  What’s a coder to do?  How about we make it retain our input types, not only that, let’s make it so we can store object types as well.

Stringification

jQuery has some nice JSON parsing utilities among other things, let’s incorporate that along with a way to serialize objects into JSON strings.  First we’ll need a JSON serializer, better known as a stringifier (No, I didn’t make that up.  That’s actually what it’s called.)

Here’s a simple method which can be used to extend jQuery and allow objects to be stringified.

jQuery.extend({
stringify : function stringify(obj) {
	if(JSON && JSON.stringify)
		return JSON.stringify(obj);

	var t = typeof (obj);
	if (t != "object" || obj === null) {
		// simple data type
		if (t == "string") obj = '"' + obj + '"';
			return String(obj);
	} else {
		// recurse array or object
		var n, v, json = [], arr = (obj && obj.constructor == Array);

		for (n in obj) {
			v = obj[n];
			t = typeof(v);
			if (obj.hasOwnProperty(n)) {
				if (t == "string") v = '"' + v + '"'; else if (t == "object" && v !== null) v = jQuery.stringify(v);
				json.push((arr ? "" : '"' + n + '":') + String(v));
			}
		}
		return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
	}
}
});

The above code is a very simple stringifier.  There are far more complex ones out there if you do a little searching, but I’ve been using this one for quite a while and it has always suited my needs.  Unfortunately however, I don’t remember where I originally found this code.  I didn’t write it, full credit goes to the original author (and if you know who that is please let me know and I’ll add an ownership clause).

Keeping Types

Now, if we combine the use of our new stringifier and the use of jQuery’s own $.parseJSON, we should be in business.  Let’s give it a try.

var myvalue = {
    first: "Bob",
    last: "Dobalina",
    age: 52
};

//let's store it
localStorage["mykey"] = $.stringify(myvalue);

//now let's retrieve it
myvalue = $.parseJSON( localStorage["mykey"] ); //returns actual JSON object

Perfect, now all our types are intact, we can store and retrieve objects ad nauseam, the world is once again a perfect place, birds are singing, no they don’t use Photoshop – super models really look like that and everything that tastes good is actually good for you.  Let’s verify our object types.

var first = myvalue.first; //returns "Bob"
var last = myvalue.last; //returns "Dobalina"
var age = myvalue.age; //returns 52

Conclusion

It’s worth being said that this point as well that local storage does have a size limitation of 5MB based on origin (which if you’re unfamiliar with is scheme + hostname + port).  So keep that in mind as you move forward with storing local information.  Hope this helps and thanks for swinging by.


2 Comments

Del · June 16, 2016 at 10:21 am

Mister Dobalina, Mister Bob Dobalina.

    godlikemouse · June 17, 2016 at 1:53 pm

    Yes, finally someone picks up on that one 🙂

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *