3

I am surprised that dart does not have a built in object-to-json and json-to-object mapper.

I read that we have to hand code the mapping ourselves, which is not pleasant.

Anyways, although I have not thoroughly tested it for my use case, I found dart-exportable to be very helpful for half of my requirement.

Any suggested package for json to object decoding?

javapadawan
  • 897
  • 6
  • 12
  • 29
  • dart:convert has [JsonCodec](https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:convert.JsonCodec); some examples [here](https://www.dartlang.org/articles/json-web-service/#parsing-json) – Amadan Sep 02 '14 at 03:10
  • @Amadan thanks, but am looking for json string to object decoder. Similar to Java's Jackson libraries. The dart-export does object to json string encoding, but does not have decoding features. – javapadawan Sep 02 '14 at 03:13
  • Oh. Okay, misunderstood. It should not be hard to build something general with `dart:mirrors`: for each key-value in an object, see if the object has a coresponding setter (or a variable?), if so, set it with the result of the function recursed for the value. – Amadan Sep 02 '14 at 03:29
  • 2
    Here is an extended discussion about this topic (not only JSON) https://groups.google.com/a/dartlang.org/forum/#!topic/misc/0pv-Uaq8FGI, maybe also https://groups.google.com/a/dartlang.org/forum/#!msg/misc/7QGLNOG14lo/iegyoJwUrCMJ There are a few problems in Dart. Mirrors causes problems when built to JavaScript (code bloat). Dart has no global unique class names (namespaces) this causes problems to find the class to deserialize into. Dart misses some features for dynamic instantiation of generic classes. There is still some work to do. – Günter Zöchbauer Sep 02 '14 at 05:05
  • I've implemented JSONIZE package just to serialize & deserialize objects of your own classes: https://pub.dev/packages/jsonize. It does not use mirrors so it is applicable to flutter projects as well – cabbi Jun 01 '22 at 12:54

2 Answers2

2

I haven't had the time to complete it yet but dartson is currently working using mirrors. However a better solution would be using a transformer when compiling to JavaScript. https://pub.dartlang.org/packages/dartson

2

Your best option is to use the Smoke library.

It's a subset of the Mirrors functionality but has both a Mirrors-based and a Codegen-based implementation. It's written by the PolymerDart team, so it's as close to "Official" as we're going to get.

While developing, it'll use the Mirrors-based encoding/decoding; but for publishing you can create a small transformer that will generate code.

Seth Ladd created a code sample here, which I extended slightly to support child-objects:

abstract class Serializable {
  static fromJson(Type t, Map json) {
    var typeMirror = reflectType(t);
    T obj = typeMirror.newInstance(new Symbol(""), const[]).reflectee;
    json.forEach((k, v) {
      if (v is Map) {
        var d = smoke.getDeclaration(t, smoke.nameToSymbol(k));
        smoke.write(obj, smoke.nameToSymbol(k), Serializable.fromJson(d.type, v));
      } else {
        smoke.write(obj, smoke.nameToSymbol(k), v);
      }
    });
    return obj;
  }

  Map toJson() {
    var options = new smoke.QueryOptions(includeProperties: false);
    var res = smoke.query(runtimeType, options);
    var map = {};
    res.forEach((r) => map[smoke.symbolToName(r.name)] = smoke.read(this, r.name));
    return map;
  }
}

Currently, there is no support to get generic type information (eg. to support List) in Smoke; however I've raised a case about this here:

https://code.google.com/p/dart/issues/detail?id=20584

Until this issue is implemented, a "good" implementation of what you want is not really feasible; but I'm hopeful it'll be implemented soon; because doing something as basic as JSON serialisation kinda hinges on it!

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275