Serializing to json

Former Member
Former Member
Is there any way (even weird one) to serialize a complex object into a JSON string? It's not directly for sending as web request's payload, so I cannot rely on the Communication functionality. I need object to be converted to json string to make some manipulations with it (for some weird hash/authentication purpose). Writing my own serializer is doable, of course, but probably too much.

Also, is there a way to desirialize a JSON string?
  • I have had this code laying around for a while. It generates JSON for built-in types, and allows you to register a type and a callback to dump objects of that type. I'll clean it up and post it.
  • using Toybox.Application;
    using Toybox.WatchUi;

    using Toybox.Lang;

    module json {

    var _type_map = {};

    function register_type(type, callback) {
    _type_map[type] = callback;
    }

    function deregister_type(type) {
    _type_map.remove(type);
    }

    //
    // return a JSON string representation of any known key type
    // throws exception if obj is not a valid key type
    //
    function _json_dumps_key(obj) {
    if (obj instanceof Lang.String) {
    return _json_dumps_string(obj);
    }
    else {
    throw new Lang.UnexpectedTypeException("UnexpectedTypeException: Expected String, given null/Boolean/Double/Float/Long/Number/Array/ByteArray/Dictionary/Object", 0, 0);
    }
    }

    //
    // return a JSON string representation of any known value type
    // throws exception if obj is not a known type
    //
    function _json_dumps_val(obj) {
    var keys = _type_map.keys();
    var vals = _type_map.values();

    for (var i = 0, j = keys.size(); i < j; ++i) {
    if (obj instanceof keys) {
    return vals.invoke(obj);
    }
    }

    return _builtin_dumps(obj);
    }

    //
    // return a JSON string representation of the given Lang.Array object
    //
    function _json_dumps_array(obj)
    {
    var n = obj.size();
    if (n == 0) {
    return "[]";
    }

    var r = "[";
    r += _json_dumps_val(obj[0]);

    for (var i = 1; i < n; ++i) {
    r += ",";
    r += _json_dumps_val(obj);
    }

    r += "]";

    return r;
    }

    //
    // return a JSON string representation of the given Lang.Dictionary object
    //
    function _json_dumps_dict(obj)
    {
    var n = obj.size();
    if (n == 0) {
    return "{}";
    }

    var k = obj.keys();
    var v = obj.values();

    var r = "{";
    r += _json_dumps_key(k[0]);
    r += ":";
    r += _json_dumps_val(v[0]);

    for (var i = 1; i < n; ++i) {
    r += ",";
    r += _json_dumps_key(k);
    r += ":";
    r += _json_dumps_val(v);
    }

    r += "}";

    return r;
    }

    //
    // return a JSON string representation of a string
    //
    function _json_dumps_string(obj) {
    return Lang.format("\"$1$\"", [ obj ]);
    }

    //
    // return a JSON string representation of a built-in object type
    //
    function _builtin_dumps(obj) {
    if (obj == null) {
    return "null";
    }
    else if (obj instanceof Lang.Boolean) {
    return obj.toString();
    }
    else if (obj instanceof Lang.Double) {
    return obj.toString();
    }
    else if (obj instanceof Lang.Float) {
    return obj.toString();
    }
    else if (obj instanceof Lang.Long) {
    return obj.toString();
    }
    else if (obj instanceof Lang.Number) {
    return obj.toString();
    }
    else if (obj instanceof Lang.String) {
    return _json_dumps_string(obj);
    }
    else if (obj instanceof Lang.Array) {
    return _json_dumps_array(obj);
    }
    else if (obj instanceof Lang.Dictionary) {
    return _json_dumps_dict(obj);
    }
    else if (obj instanceof Lang.ByteArray) {
    return obj.toString();
    }

    throw new Lang.UnexpectedTypeException("UnexpectedTypeException: Expected null/Boolean/Double/Float/Long/Number/String/Array/ByteArray/Dictionary, given Object", 0, 0);
    }

    //
    // return a JSON string representation of any known type
    //
    function dumps(obj) {
    return _json_dumps_val(obj);
    }
    }

    class SampleApp extends Application.AppBase {

    hidden var _member1;
    hidden var _member2;

    function initialize() {
    AppBase.initialize();

    _member1 = 17;
    _member2 = 31;
    }

    function onStart(params) {
    json.register_type(SampleApp, self.method(:dumps));
    }

    function onStop(params) {
    json.deregister_type(SampleApp);
    }


    function dumps(obj) {
    var rep = {
    "member1" => _member1,
    "member2" => _member2
    };

    return json.dumps(rep);
    }

    function getInitialView() {

    System.println(json.dumps({ "one" => 1, "two" => 2.0d, "three" => [ { "a" => [] } ] }));
    System.println(json.dumps(self));

    try {
    System.println(json.dumps({ 1 => "one", "two" => 2.0d }));
    }
    catch(e) {
    e.printStackTrace();
    }

    return [ new WatchUi.View() ];
    }
    }
    [/code]

    It produces this...

    {"two":2.000000,"three":[{"a":[]}],"one":1}
    {"member1":17,"member2":31}
    UnexpectedTypeException: Expected String, given null/Boolean/Double/Float/Long/Number/Array/ByteArray/Dictionary/Object
    _json_dumps_key in D:\eclipse-workspace\Sample\source\SampleApp.mc:23
    _json_dumps_dict in D:\eclipse-workspace\Sample\source\SampleApp.mc:77
    _builtin_dumps in D:\eclipse-workspace\Sample\source\SampleApp.mc:123
    _json_dumps_val in D:\eclipse-workspace\Sample\source\SampleApp.mc:37
    dumps in D:\eclipse-workspace\Sample\source\SampleApp.mc:133
    getInitialView in D:\eclipse-workspace\Sample\source\SampleApp.mc:173
  • Former Member
    Former Member over 6 years ago
    Travis.ConnectIQ Thanks a lot!