Reputation: 83
I have a Typescript class that has methods on it. I end up transferring these objects from the server to the browser through REST where the JSON representation of course loses the methods and prototype information. I want to turn the JSON back into the object with the methods so I can use them on the client side. I've been using a static method that will take in the JSON object and recreate my object but it's a pretty manual process.
Is there a better way to do it?
class Rectangle {
constructor(public width: number, public height: number) { }
public getArea(): number {
return this.width * this.height;
}
public static fromPojo(pojo: any): Rectangle {
if (pojo
&& pojo.width !== undefined
&& pojo.height !== undefined) {
return new Rectangle(pojo.width, pojo.height);
}
throw new Error("Pojo is not a Rectangle");
}
}
let rect = new Rectangle(10, 20);
console.log(rect.getArea()); // 200
let json = JSON.stringify(rect); // {"width":10,"height":20}
let rectFromJson = <Rectangle>JSON.parse(json);
console.log(rectFromJson.getArea()); // Error: rectFromJson.getArea is not a function
let rectFromPojo = Rectangle.fromPojo(JSON.parse(json));
console.log(rectFromPojo.getArea()); // 200
If a property gets added to the object, I have to make sure I update the fromPojo() method, making this tactic error-prone. Ideally I want to get rid of the static fromPojo(pojo) method in favor of something more dependable/automatic.
Update: Here's the code working with Serializr, as suggested by Nick Uraltsev. Much less error prone but loses the constructor params. I would prefer to be able to keep the constructor params.
import { deserialize, serializable, serialize } from "serializr";
class Rectangle {
@serializable
public width: number;
@serializable
public height: number;
public getArea(): number {
return this.width * this.height;
}
}
let rect = new Rectangle();
rect.width = 10;
rect.height = 20;
let serJson = serialize(rect);
console.log(serJson); // { width: 10, height: 20 }
let reconstructedRect = deserialize(Rectangle, serJson);
console.log(reconstructedRect.getArea()); // 200
Upvotes: 0
Views: 157
Reputation: 25897
Take a look at Serializr. Looks like it does exactly what you need.
Upvotes: 1