Its easy to load JSON into an object in javascript using eval or JSON.parse.
But if you have a proper "class" like function, how do you get the JSON data into it?
E.g.
function Person(name) {
  this.name=name;
  this.address = new Array();
  this.friendList;
  this.promote = function(){
     // do some complex stuff
  }
  this.addAddress = function(address) {
    this.address.push(address)
  }
}
var aPersonJSON = '{\"name\":\"Bob\",\"address\":[{\"street\":\"good st\",\"postcode\":\"ADSF\"}]}'
var aPerson = eval( "(" + aPersonJSON + ")" ); // or JSON.parse
//alert (aPerson.name);    // Bob
var someAddress = {street:"bad st",postcode:"HELL"};
//alert (someAddress.street); // bad st
aPerson.addAddress(someAddress); // fail!
The crux is I need to be able to create proper Person instances from JSON, but all I can get is a dumb object. Im wondering if its possible to do something with prototypes?
I dont want to have to parse each line of the JSON and assign each variable to the coresponding functions attributes, which would be too difficult. The actualy JSON and functions I have are much more complicated than the example above.
I am assuming one could JSONify the functions methods into the JSON string, but as I need to keep the resultant data as small as possible this is not an option - I only want to store and load the data, not the javascript code for the methods.
I also dont want to have to put the data loaded by JSON as a sub object if I can help it (but might be the only way), e.g.
function Person(name) {
  this.data = {};
  this.data.name=name;
}
var newPerson = new Person("");
newPerson.data = eval( "(" + aPersonJSON + ")" );
alert (newPerson.data.name); // Bob
Any ideas?
You need to use a reviver function:
// Registry of types
var Types = {};
function MyClass(foo, bar) {
  this._foo = foo;
  this._bar = bar;
}
Types.MyClass = MyClass;
MyClass.prototype.getFoo = function() {
  return this._foo;
}
// Method which will provide a JSON.stringifiable object
MyClass.prototype.toJSON = function() {
  return {
    __type: 'MyClass',
    foo: this._foo,
    bar: this._bar
  };
};
// Method that can deserialize JSON into an instance
MyClass.revive = function(data) {
  // TODO: do basic validation
  return new MyClass(data.foo, data.bar);
};
var instance = new MyClass('blah', 'blah');
// JSON obtained by stringifying an instance
var json = JSON.stringify(instance); // "{"__type":"MyClass","foo":"blah","bar":"blah"}";
var obj = JSON.parse(json, function(key, value) {
  return key === '' && value.hasOwnProperty('__type')
    ? Types[value.__type].revive(value)
    : this[key];
});
obj.getFoo(); // blah
No other way really...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With