1

I am trying to read a JSON code which is compatible with a Swift program into a flutter app. The structure is like this:

{
  "tagDict" : {
    "abc" : {
      "helpHdr" : "short text1",
      "helpText" : "long text1"
    },
    "def" : {
      "helpHdr" : "short text2",
      "helpText" : "long text2"
    }
  }
}

This creates in Swift a dictionary and shall create a map in Dart of the type {key : {helpHdr, helpText}}. A variable based on this should enable label = myVariable[tag].helpHdr, or staying with the example label = myVariable["abc"].helpHdr should assign "short text1" to label

To parse nested arrays I am using this, however, no clue how to transfer this to such a nested map.

class MyClass {
  List<MySubClass> myArray;
  MyClass({
    this.myArray,
  });

  factory MyClass.fromJson(Map<String, dynamic> parsedJson){
    var list = parsedJson['myArray'] as List;
    List<MySubClass> listObject = list.map((i) => MySubClass.fromJson(i)).toList();
    return new MyClass(
      myArray: listObject,
    );
  }
}

class MySubClass {
  int id;
  String text1;
  String text2;
  MySubClass({
    this.id,
    this.text1,
    this.text2,
  });

  factory MySubClass.fromJson(Map<String, dynamic> parsedJson){
    return new MySubClass(
      id: parsedJson['id'],
      text1: parsedJson['text1'],
      text2: parsedJson['text2'],
    );
  }
}
2
  • What is wrong with what you already have? Why do you need a nested map? But if you really need a nested map you can instead of using a subclass, use a method that does the same thing as the subclass.fromJson but returns a map. Commented Aug 19, 2020 at 15:51
  • Try this. You can define how the class will look, and let the build runner take care of everything else. flutter.dev/docs/development/data-and-backend/… Commented Aug 19, 2020 at 16:03

3 Answers 3

1

If I'm correct you want to parse your json into Data class object. If that's right then you can try this

void main() {
  List<MyClass> myClassList = new List<MyClass>();
  Map map = {
    "tagDict": {
      "abc": {"helpHdr": "short text1", "helpText": "long text1"},
      "def": {"helpHdr": "short text2", "helpText": "long text2"}
    }
  };

  map['tagDict'].forEach((key, value) {
    value['id'] = key;
    myClassList.add(MyClass.fromJson(value));
  });

  myClassList.forEach((myClass) {
    print(myClass.id);
    print(myClass.helpHdr);
    print(myClass.helpText);
    print("--------------------\n");
  });
}

class MyClass {
  String id;
  String helpHdr;
  String helpText;

  MyClass({this.id, this.helpHdr, this.helpText});

  MyClass.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    helpHdr = json['helpHdr'];
    helpText = json['helpText'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['helpHdr'] = this.helpHdr;
    data['helpText'] = this.helpText;
    return data;
  }
}

This is the Output:

abc
short text1
long text1
--------------------

def
short text2
long text2
--------------------
Sign up to request clarification or add additional context in comments.

2 Comments

not sure. need to run to a meeting so will check this later in more detail. However, I want to have a dictionary of the kind that I do not have to search where id = "abc" and then print the related helpHdr but to use myClassList["abc"].helpHdr instead.
Though this does not provide the intended data structure, it provided me the building blocks towards the solution. Thanks!
0
class TagRes {
TagDict tagDict;

TagRes({this.tagDict});

TagRes.fromJson(Map<String, dynamic> json) {
tagDict =
    json['tagDict'] != null ? new TagDict.fromJson(json['tagDict']) : null;
}

Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.tagDict != null) {
  data['tagDict'] = this.tagDict.toJson();
}
return data;
}
 }

class TagDict {
 Abc abc;
Abc def;

TagDict({this.abc, this.def});

 TagDict.fromJson(Map<String, dynamic> json) {
  abc = json['abc'] != null ? new Abc.fromJson(json['abc']) : null;
  def = json['def'] != null ? new Abc.fromJson(json['def']) : null;
 }

 Map<String, dynamic> toJson() {
  final Map<String, dynamic> data = new Map<String, dynamic>();
  if (this.abc != null) {
  data['abc'] = this.abc.toJson();
  }
   if (this.def != null) {
  data['def'] = this.def.toJson();
 }
  return data;
 }
 }

class Abc {
String helpHdr;
  String helpText;

  Abc({this.helpHdr, this.helpText});

  Abc.fromJson(Map<String, dynamic> json) {
   helpHdr = json['helpHdr'];
   helpText = json['helpText'];
 }

 Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['helpHdr'] = this.helpHdr;
data['helpText'] = this.helpText;
return data;
 }
}

Comments

0

Based on Tipu's answer, I came up with the following code which creates the intended dictionary (or map in Dart - why couldn't they stick to standard terminology like arrays etc?!)

class TaskTags {
  var tagDict = Map<String, TaskTag>();
  TaskTags({
    this.tagDict,
  });

  factory TaskTags.fromJson(Map<String, dynamic> json){
    var innerMap = json['tagDict'];
    var tagMap = Map<String, TaskTag>();
    innerMap.forEach((key, value) {
      tagMap.addAll({key: TaskTag.fromJson(value)});
    });
    return new TaskTags(
      tagDict: tagMap,
    );
  }
}

class TaskTag {
  String helpHdr;
  String helpText;
  TaskTag({
    this.helpHdr,
    this.helpText,
});

  factory TaskTag.fromJson(Map<String, dynamic> json){
    return new TaskTag(
      helpHdr: json['helpHdr'],
      helpText: json['helpText'],
    );
  }
}

This creates the following map

{"abc“ : {helpHdr: "short text1", helpText: "long text1"}, "def“ : {helpHdr: "short text2", helpText: "long text2"}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.