hansa
hansa

Reputation: 139

Does LocalStorage support Custom (i.e. non-primitive type) Object Storage and Retrieval in any way?

So I would like to pass an object "Hello" in JavaScript file hello.js to another JavaScript file chat.js.

Hello contains members such as Strophe.Connections, and others.

I read that I could use LocalStorage, i.e. LocalStorage.SetItem("Hello", Hello) and then retrieve the object using LocalStorage.getItem("Hello").

This did not work for me, so I searched a bit more and found JSON stringify, e.g. someone at Storing Objects in HTML5 localStorage and also at How to send javascript object from one page to another page? suggested the use of stringify.

So I tried this as well, and here is the relevant code of Hello.js:

var Hello = {
connection: null,
start_time: null,
log: function (msg) {
    $('#log').append("<p>" + msg + "</p>");
},

send_ping: function (to) {
    var ping = $iq({
        to: to,
        type: "get",
        id: "ping1"}).c("ping", {xmlns: "urn:xmpp:ping"});

    Hello.log("Sending ping to " + to + ".");
    console.log("Sending ping to " + to + ".");

    Hello.start_time = (new Date()).getTime();
    Hello.connection.send(ping);
},

handle_pong: function (iq) {
    var elapsed = (new Date()).getTime() - Hello.start_time;
    Hello.log("Received pong from server in " + elapsed + "ms.");
    console.log('Received pong from server in " + elapsed + "ms.');     
    localStorage.setItem("hello", JSON.stringify(Hello));
    return false;
    }
};

Here is chat.js

var Hello = {
conn: null
};

$(document).ready(function(e) { 
    Hello = JSON.parse(localStorage.getItem("hello"));
    $('#input3').bind('click', 
    Hello.connection.send("someStanza"))});

On line Hello = JSON.parse(localStorage.getItem("hello")); I try to restore the object.

And 2 line beow I call Hello.connection.send. However, here it becomes clear that I was not able to pass and restore the Hello object correctly. In Google Chrome JavaScript debugger, for example, I get an error at that line stating "Uncaught TypeError: undefined is not a function", which I would say means basically that the Chrome JS engine was not able to find any connection.send member in the Hello Object.

This leaves two options. Either what I am trying to do (passing an object that is not a primitive data type) is not possible in the way I am doing it. Or, that it is possible in the way I am doing it, and there is simply some other error/problem I am not seeing.

If it is possible, what am I doing wrong?

If it isn't possible to pass a non-primitive data type in this way, how else can I do it?

Hope I made myself clear enough for understanding,

Thanks, br,

Chris

Upvotes: 0

Views: 243

Answers (1)

Jack
Jack

Reputation: 9388

One workaround is to toString the function and then store it in localStorage. Then, when you retrieve the object from localStorage, you eval the function. Here's a quick demo that demonstrates (it's very stupid and can be optimized/enhanced based on your needs...):

http://jsfiddle.net/nmef7utv/

function pack(obj){
    var packedObj = {};
    for (key in obj) {

        // If obj property is a function, toString() it.
        if (obj[key] && obj[key].constructor === Function) {
            packedObj[key] = obj[key].toString();
        } else {
            packedObj[key] = obj[key];
        }
    }

    return JSON.stringify(packedObj);
}

function unpack(obj) {
    // Temporary variable to hold eval'd func, if needed
    var temp;

    // Parse obj to loop
    obj = JSON.parse(obj);

    for (key in obj) {
        if (typeof obj[key] === "string") {
            eval('temp =' + obj[key]);

            // Assign eval'd function
            obj[key] = temp;
        } else {
            obj[key] = obj[key];
        }
    }
    return obj;
}

In the fiddle, I have:

// Packed Item
localStorage.setItem('test', pack(Hello));

// Unpack
testObj = unpack(localStorage.getItem('test'));
testObj.handle_pong();

Hope this is of help!

Upvotes: 1

Related Questions