Serializing?
Serialization is the process of converting complex objects into a data format that can be easily stored or sent across a network connection. In JavaScript, serialization and deserialization of objects can be achieved by using JSON.stringify()
and JSON.parse()
.
Example
// Let's say you have a simple json response from your server. var jsonResponse = "{firstName:\"John\", lastName:\"Doe\"}"; // If you want to deserialize this object, you can use JSON.parse(). var jsonParsed = JSON.parse(jsonResponse); // An object with the correct properties will be returned console.log(jsonParsed.firstName); // Prints 'John' console.log(jsonParsed.lastName); // Prints 'Doe' // If you want to serialize the object back into a string represantation, you can use JSON.stringify() var serializedJson = JSON.stringify(parsedJson); console.log(serializedJson); // Prints '{firstName:"John", lastName:"Doe"}'
The Problem?
Things start to get complicated when you are using TypeScript
or ES6
and the response from the server doesn’t really match your client data structure. In this case you have an extra step of copying the properties from the parsed json response into your custom model object. When you want to send the data back to the server you have to copy the properties again into their original format.
Example
// The response from the server let response:string = "{first_name:\"John\", last_name:\"Doe\"}"; // Your model class class UserProfile { firstName:string; lastName:string; } let jsonParsed = JSON.parse(response); var userProfile = new UserProfile(); userProfile.firstName = jsonParsed.first_name; userProfile.lastName = jsonParsed.last_name; // When you want to send the data back to the server you have to do the same things as above but in reverse. let dataToSend = { first_name: userProfile.firstName, last_name: userProfile.lastName }; let dataAsString = JSON.stringify(dataToSend); console.log(dataAsString); // Prints {first_name:"John", last_name:"Doe"} // It's easy to see that when you have lots of properties this gets very messy, very quickly
Solution? Introducing TS Serializer
Some time ago I have started using TypeScript for most of my projects. One of those projects had a very different data structure between the server and the client. After getting very frustated with writing serialization and deserialization methods for my data models, I came up with the ideea of ts-serializer. ts-serializer
is a collection of typescript decorators and helper classes that allows the developer to easily serialize and deserialize complex objects to and from JSON objects.
Installation
Using NPM
npm install --save ts-serializer
Build from Git
git clone https://github.com/dpopescu/ts-serializer.git cd ts-serializer npm install npm run build
The library will be in the dist
folder
Usage
You start by importing the library decorators and the Serializable abstract class
import {Serialize, SerializeProperty, Serializable} from 'ts-serializer';
In order to mark a class as serializable, you need to use the Serialize decorator and extend the abstract Serializable class.
@Serialize({}) class Profile extends Serializable { }
The Serialize
decorator implements in the target class the serialize and deserialize methods required by the Serializable
class.
By default, the library does not serialize class properties if are not marked for serialization. In order to declare a property as serializable you use the SerializeProperty decorator.
@Serialize({}) class Profile extends Serializable { @SerializeProperty({}) firstName:string; @SerializeProperty({}) lastName:string; }
After the class and the class properties are marked as serializable, you can use the serialize
and deserialize
methods and ts-serializer
will take care of things for you.
Full Example
import {Serialize, SerializeProperty, Serializable} from 'ts-serializer'; @Serialize({}) class User extends Serializable { @SerializeProperty({ map: 'first_name' }) firstName:string; @SerializeProperty({ map: 'last_name' }) lastName:string; } @Serialize({}) class Profile extends Serializable { @SerializeProperty({ type: User }) user: User; } let data = { user: { first_name: 'John', last_name: 'Doe' } }; let instance:Profile = new Profile(); instance.deserialize(data); console.log(instance.user.firstName); // Prints 'John' console.log(instance.user.lastName); // Prints 'Doe' console.log(instance.serialize()); // Prints {"user":{"first_name":"John", "last_name":"Doe"}} console.log(instance.user.serialize()); // Prints {"first_name":"John", "last_name":"Doe"}
For more information about the library check out serializer.dpopescu.me and ts-serializer Github page