I try to convert an object to JSON.
var obj = { "dt": new DateTime.now() };
var s = stringify(obj);
The runtime throws an exception: "Calling toJson method on object failed."
That's expected since DateTime class doesn't have toJson method.
But what should I do in this case?
Javascript's JSON.stringify
function has an optional argument replacer which allows me to provide my own way of serialization of any object even if the object has no toJson method. Is there any similar facility in Dart or maybe I can extend somehow DateTime class with my own toJson method?
Zdeslav Vojkovic's answer is outdated now.
The JSON.encode()
method in dart:convert
has an optional toEncodable
method that is invoked for objects that are not natively serializable to JSON. It's then up to the user to provide a closure that returns an appropriate serialization of the DateTime.
IMO, it's a flaw in dart:json
library that stringify
doesn't support additional callback to serialize types lacking the implementation of toJson
. Strangely enough, parse
function does support reviver
argument to customize the deserialization process. Probably the reason was along the lines that user can add toJson
for their on types, and core library will take care of 'native' types, but DateTime
was omitted (maybe because date serialization in JSON is not really a straightforward story).
Maybe the goal of the team was to use custom types instead of Maps (which is nice), but the drawback here is that if your custom type contains 10 other properties and 1 which is of DateTime
type, you need to implement toJson
which serializes all of them, even integers and strings. Hopefully, once when Mirror API is ready, there will be libraries that implement serialization 'out-of-band' by reading the reflected info on type, see lower for an example. The promise of Dart is that I would be able to use my types both on server and client, but if I have to manually implement serialization/deserialization for all my models then it is too awkward to be usable.
it also doesn't help that DateTime
itself is not very flexible with formatting, as there are no other methods besides toString
which returns the format useless for serialization.
So here are some options:
- wrap (or derive from)
DateTime
in your own type which provides toJson
- patch
json.stringifyJsonValue
and submit the change or at least submit an issue :)
- use some 3-rd party library like
json-object
(just an example, it also doesn't support DateTime
serialization, AFAIK
I am not really happy with any of them :)