Parsing JSON with Dart

I want to be able to parse a string for an object that I can access using dot notation, for example. myobject.property, instead of designating an array, for example. MyObject ['property']. Array designation works great. Here is what I still have.

I have XML:

<level1 name="level1name"> <level2 type="level2Type"> <entry>level2entry</entry> <entry>level2entry</entry> </level2> </level1> 

What converts to JSON:

 { "level1": { "name": "level1name", "level2": { "type": "level2Type", "entry": [ "level2entry", "level2entry" ] } } } 

I have the following Dart code:

 Object jsonObject = JSON.parse("""{ "level1": { "name": "level1name", "level2": { "type": "level2Type", "entry": [ "level2entry", "level2entry" ] } } } """); print("my test 1 == ${jsonObject}"); print("my test 2 == ${jsonObject['level1']}"); print("my test 3 == ${jsonObject['level1']['name']}"); 

which produce the (desired) output:

 my test 1 == {level1: {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}}} my test 2 == {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}} my test 3 == level1name 

But when I try:

 print("my test 1 == ${jsonObject.level1}"); 

I get the following:

 Exception: NoSuchMethodException : method not found: 'get:level1' Receiver: {level1: {name: level1name, level2: {type: level2Type, entry: [level2entry, level2entry]}}} Arguments: [] Stack Trace: 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:717 col:3 

Ideally, I need an object that I can access using dot notation and without a compiler warning about an object that does not have a property. I tried the following:

 class MyJSONObject extends Object{ Level1 _level1; Level1 get level1() => _level1; set level1(Level1 s) => _level1 = s; } class Level1 { String _name; String get name() => _name; set name(String s) => _name = s; } ... MyJSONObject jsonObject = JSON.parse("""{ "level1": { "name": "level1name", "level2": { "type": "level2Type", "entry": [ "level2entry", "level2entry" ] } } } """); ... print("my test 1 == ${jsonObject.level1.name}"); 

but instead of giving me "level1name", as I hope, I get:

 Exception: type 'LinkedHashMapImplementation<String, Dynamic>' is not a subtype of type 'MyJSONObject' of 'jsonObject'. 

What am I doing wrong here? Is there a way to do what I'm trying? Thanks.

+8
json dart
source share
2 answers

Currently JSON.parse returns only lists (array), maps, strings, num, bool and null ( api ref ).

I suspect that until the reflection turns into a language, it will not be able to rebuild the objects based on the keys found in json.

However, you could create a constructor in MyJsonObject that takes a string called JSON.parse and assigns different values.

Something like this works in the dart editor:

 #import("dart:json"); class Level2 { var type; var entry; } class Level1 { var name; var level2; } class MyJSONObject { Level1 level1; MyJSONObject(jsonString) { Map map = JSON.parse(jsonString); this.level1 = new Level1(); level1.name = map['level1']['name']; level1.level2 = new Level2(); level1.level2.type = map['level1']['level2']['type']; //etc... } } main() { var obj = new MyJSONObject(json); print(obj.level1.level2.type); } 

The non-trivial version needs some loops and possible recursion if you have deeper nested levels.

Update: I hacked into a non-trivial version (inspired by the post below), it on github (also accepting Seth re the constructor comments):

+12
source share
Chris is absolutely right. I add that the JSON parser could be changed to return a slightly richer object (something like JsonMap instead of pure Map ), which would allow jsonObj.property implement noSuchMethod . Obviously this will be worse than jsonObj['property'] .
+4
source share

All Articles