Skip to content

Adding Custom Types to the Serialiser

Rob Evans edited this page May 24, 2016 · 3 revisions

To understand how types are added to the serialiser let's take a look at the code used in ForerunnerDB to register a handler for the native JavaScript Date() object instance.

fdb.serialiser.registerHandler('$date', function (objInstance) {
	if (objInstance instanceof Date) {
		// Augment this date object with a new toJSON method
		objInstance.toJSON = function () {
			return "$date:" + this.toISOString();
		};

		// Tell the converter we have matched this object
		return true;
	}

	// Tell converter to keep looking, we didn't match this object
	return false;
}, function (data) {
	if (typeof data === 'string' && data.indexOf('$date:') === 0) {
		return self.convert(new Date(data.substr(6)));
	}

	return undefined;
});

Custom type handlers are declared via the fdb.serialiser.registerHandler() method. This method takes three arguments:

  1. The name of the handler (this can be anything you like but usually a good idea to denote what marker you will be using e.g. $date)
  2. The encoder method
  3. The decoder method

Arguments 2 and 3 are the complex parts of this so let's examine what we are doing.

When ForerunnerDB calls the encoder method it will pass you a single argument which could be ANY data type. Your first check should be to ensure the argument is the type you want to act upon. If it isn't you should return false which indicates to ForerunnerDB that your encoder didn't want to do any work on that data.

Once you know you are working with the correct data instance you must modify the instance's .toJSON() method to return encoded data that your decoder method will be able to identify and decode. That's all there is to the encoder method... it just modifies the toJSON of an instance and returns true to tell ForerunnerDB it has modified the instance.

One important caveat... the encoder's toJSON() method must return a string. It's a hassle but if we don't return a string things can start becoming very complex. That's why the date example code above returns "$date:" + the iso string of the date... we added a $date marker to the string so we can identify it later, then we have a colon and the rest of our string is the ISO date. This allows our decoder method to identify that the string should be converted back to a Date() object, and provides the date ISO string data to do so.

The decoder method should check it is working on a string and that the string matches the marker you created in your encoder method's toJSON function. Once you have identified that the string contains your marker, you should convert it back to the native instance you want and return that instance. If you do not want to work on the data (maybe it doesn't match your marker etc) then simply return undefined.