Serializing an ES6 class object as JSON
Solution 1
As with any other object you want to stringify in JS, you can use JSON.stringify
:
JSON.stringify(yourObject);
class MyClass {
constructor() {
this.foo = 3
}
}
var myClass = new MyClass()
console.log(JSON.stringify(myClass));
Also worth noting is that you can customize how stringify
serializes your object by giving it a toJSON
method. The value used to represent your object in the resulting JSON string will be the result of calling the toJSON
method on that object.
Solution 2
I know this question is old but I've been clawing my eyes out until I wrote a compact real, "safe", solution.
Deserialization returns objects that still have working methods attached to them.
The only thing you need to do is register the classes you want to use in the constructor of the serializer.
class Serializer{
constructor(types){this.types = types;}
serialize(object) {
let idx = this.types.findIndex((e)=> {return e.name == object.constructor.name});
if (idx == -1) throw "type '" + object.constructor.name + "' not initialized";
return JSON.stringify([idx, Object.entries(object)]);
}
deserialize(jstring) {
let array = JSON.parse(jstring);
let object = new this.types[array[0]]();
array[1].map(e=>{object[e[0]] = e[1];});
return object;
}
}
class MyClass {
constructor(foo) {this.foo = foo;}
getFoo(){return this.foo;}
}
var serializer = new Serializer([MyClass]);
console.log(serializer.serialize(new MyClass(42)));
//[0,[["foo",42]]]
console.log(serializer.deserialize('[0,[["foo",42]]]').getFoo());
//42
The above should be enough to get you going, but more details and minified version can be found here.
Solution 3
I've came across this library which does both serialization and deserialization of complex objects (including nested objects and arrays):
https://github.com/typestack/class-transformer
It has at least two methods:
plainToClass() -> json obj to class
classToPlain() -> class to json obj
Solution 4
It's easy if you don't mind passing the class definition into decode.
// the code
const encode = (object) => JSON.stringify(Object.entries(object))
const decode = (string, T) => {
const object = new T()
JSON.parse(string).map(([key, value]) => (object[key] = value))
return object
}
// test the code
class A {
constructor(n) {
this.n = n
}
inc(n) {
this.n += n
}
}
const a = new A(1)
const encoded = encode(a)
const decoded = decode(encoded, A)
decoded.inc(2)
console.log(decoded)
Solution 5
I made a module esserializer to solve this issue. It is a utility to serialize JavaScript class instance, and deserialize the "serialized-text" into an instance object, with all Class/Property/Method etc. retained.
To serialize an instance, just invoke the serialize()
method:
const ESSerializer = require('esserializer');
let serializedString = ESSerializer.serialize(anObject);
The internal mechanism of serialize()
is: save the instance' property and its class name information into string, recursively.
To deserialize from string, just invoke the deserialize()
method, passing all involved classes as parameter:
const ESSerializer = require('esserializer');
const ClassA = require('./ClassA');
const ClassB = require('./ClassB');
const ClassC = require('./ClassC');
let deserializedObj = ESSerializer.deserialize(serializedString, [ClassA, ClassB, ClassC]);
The internal mechanism of deserialize()
is: manually compose the object with its prototype information, recursively.
eugene
I am working on littlehome.kr If you'd like to give a hand, please join us.
Updated on December 23, 2021Comments
-
eugene over 2 years
class MyClass { constructor() { this.foo = 3 } } var myClass = new MyClass()
I'd like to serialize
myClass
object to json.One easy way I can think of is, since every member is actually javascript object (array, etc..) I guess I can maintain a variable to hold the member variables.
this.prop.foo = this.foo
and so on.I expected to find a
toJSON/fromJSON
library for class objects since I used them with other languages such as swift/java, but couldn't find one for javascript.Maybe class construct is too new, or what I'm asking can be somehow easily achieved without a library.
-
steve almost 7 yearsHow to unserialize it .
-
nbrooks almost 7 years@IWuZhuo
JSON.parse( string )
-
steve almost 7 yearsThanks. JSON.parse( string ) return a json object . not an instance of MyClass.
-
Antero Duarte almost 7 years@IWuZhuo for that I would suggest that you create a static method on your class that takes in that object and returns an instance of the class by creating the object with the properties in the JSON. There is no way of doing this in Javascript out of the box, but I would say it's quite easy to write it yourself
-
Dmitri Nesteruk about 5 yearsThis example does not handle recursive object initialization. If a class
Person
contains a memberAddress
, after deserialization you will be unable to call onAddress
's methods. -
vir us about 3 yearsto unserialize, it's not that straightforward especially when it comes to complex nested objects, but there is a lightweight library that does that. Checkout my answer below for details.
-
Dean about 3 yearsThis is a great solution if you don't use nested objects. But as you can see this fails when you try to do that: replit.com/@deanc1/PerfumedBustlingAngle#index.js
-
Dean about 3 yearsreplit.com/@deanc1/SickOblongMicroinstruction#index.js This works well on one-level deep nested objects - Thank you @shaochuancs
-
Talal916 about 2 yearsWhile this seems like an interesting library, can we refrain from using phrases like "the modern approach" when something very clearly is not an industry standard approach. As of this comment, this library has a single contributor, 0 stars on Github and 16 weekly downloads. npmjs.com/package/@badcafe/jsonizer
-
GaryBishop almost 2 yearsIt appears to work if you give it both classes on initialization.