Search code examples
javascriptjqueryjsonajaxsessionstorage

Save JavaScript prototype based objects in sessionStorage?


var obj = { 
conn : null,
first : function(thisIdentity) {
    "use strict";
    var myObj = this;
    $(document).on('click', thisIdentity, function(e) {
    e.preventDefault();
    $.ajax ({ 
        url : some value,
        // other parameters
        success : function(data) {
            myObj.conn = new Connection(data.user_id, "127.0.0.1:80");
            sessionStorage.setItem('connection', JSON.stringify(myObj.conn));
           }
        });
   },
second : function(thisIdentity) {
    "use strict";
    var myObj = this;
    var conntn = sessionStorage.getItem('connection');
        $(document).on('click', thisIdentity, function(e) {
        e.preventDefault();
        $.ajax ({ 
            url : some value,
            // other parameters
            success : function(data) { 
            var parsedConnection = JSON.parse(conntn);
            parsedConnection.sendMsg(data.id, data.nid);
        }
      });
    }
};
var Connection = (function() {
    function Connection(uid, url) {
       this.uid = uid;
       this.open = false;
       this.socket = new WebSocket("ws://"+url);
       this.setupConnectionEvents();
    },
Connection.prototype = {
    sendMsg : function(id, nid) {
        alert("Working");
    },
    // other functions
    }
})();

So connection is made in the AJAX callback function of first and I store the object in the sessionStorage via JSON but when I use it in the AJAX callback of second then error is coming that

TypeError: parsedConnection.sendMsg is not a function

Now I understand that may be it is because JSON can be used to store plain objects not prototype-based objects.

My question is : Can any one tell me how to store prototype-based objects via JSON or any other way to implement this?

I don't want to use eval. Any code, reference would be much appreciated. Thanks!

UPDATE

I did as @Dan Prince mentioned but then a new problem occurred that now when in sendMsg function I use

this.socket.send(JSON.stringify({
   action: 'message',
   rec: receiver,
   msg: message
}));

Then it stays

InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable

Any inputs? Thanks!


Solution

  • You could probably hack your own solution into place by storing the prototype as a property of the object, then reinstantiating it with Object.create after you read it, but the real question is why do you want to do this in the first place?

    I would suggest writing a serialize method on Connection's prototype, which exposes only the essential information (there's no sense serializing a web socket for example).

    Connection.prototype.toJSON = function() {
      return JSON.stringify({
        uid: this.uid,
        url: this.url,
        open: this.open
      });
    };
    

    Then use this method when you save the connection object into session storage.

    myObj.conn = new Connection(data.user_id, "127.0.0.1:80");
    sessionStorage.setItem('connection', myObj.conn.toJSON());
    

    Each saved connection now has the minimum amount of data you need to call the constructor and recreate the instance.

    When you load a connection from session storage, parse it and pass the values back into the constructor.

    var json = sessionStorage.getItem('connection');
    var data = JSON.parse(json);
    var connection = new Connection(data.uid, data.url)
    
    // ...
    connection.sendMsg(data.id, data.nid);
    

    This will recreate the correct prototype chain in a natural and predictable way.