1
class Foo {
  DateTime a;
  String b;
}

List<List<Foo>> nestedFooList;

I'd like to convert nestedFooList to string and store it on sharedPreferences.

I can handle and convert List<Foo> to string.

I got my code from https://stackoverflow.com/a/61317989/433570

class Music {
  final int id;
  final String name, size, rating, duration, img;
  bool favorite;

  Music({
    this.id,
    this.rating,
    this.size,
    this.duration,
    this.name,
    this.img,
    this.favorite,
  });

  factory Music.fromJson(Map<String, dynamic> jsonData) {
    return Music(
      id: jsonData['id'],
      rating: jsonData['rating'],
      size: jsonData['size'],
      duration: jsonData['duration'],
      name: jsonData['name'],
      img: jsonData['img'],
      favorite: false,
    );
  }

  static Map<String, dynamic> toMap(Music music) => {
        'id': music.id,
        'rating': music.rating,
        'size': music.size,
        'duration': music.duration,
        'name': music.name,
        'img': music.img,
        'favorite': music.favorite,
      };

  static String encode(List<Music> musics) => json.encode(
        musics
            .map<Map<String, dynamic>>((music) => Music.toMap(music))
            .toList(),
      );

  static List<Music> decode(String musics) =>
      (json.decode(musics) as List<dynamic>)
          .map<Music>((item) => Music.fromJson(item))
          .toList();
}
eugene
  • 39,839
  • 68
  • 255
  • 489

2 Answers2

0

Its mainly String jsonText = jsonEncode( nestedFooList );

jsonEncode can encode basic types, maps and lists. It will call a method toJson in the class to encode it. So your class should look like this:

class Foo() {
  DateTime a;
  String b;

  String toJson() {
    return jsonEncode(getAsMap());
  }

  Map<String,dynamic> getAsMap() {
    return {
      'a': a.toString(),  // DateTime as string
      'b': b,
    };
  }

Thats the encoding part. Decoding the resulting json string must instantiate your classes and put them into nested lists like. Full example here:

class Foo {
  DateTime a;
  String b;

  String toJson() {
    return jsonEncode(getAsMap());
  }

  Map<String, dynamic> getAsMap() {
    return {
      'a': a.toString(),
      'b': b,
    };
  }

  void fillFromMap(Map<String, dynamic> map) {
    a = DateTime.parse(map['a']);
    b = map['b'];
  }

  String toString() {
    return '$a - $b';
  }
}

void main(List<String> args) {
  Foo foo11 = Foo()
    ..a = DateTime.now()
    ..b = 'foo1.1';
  Foo foo12 = Foo()
    ..a = DateTime.now()
    ..b = 'foo1.2';
  Foo foo21 = Foo()
    ..a = DateTime.now()
    ..b = 'foo2.1';
  Foo foo22 = Foo()
    ..a = DateTime.now()
    ..b = 'foo2.2';
  List<List<Foo>> nestedFooList = [
    [foo11, foo12],
    [foo21, foo22]
  ];
  String jsonText = jsonEncode(nestedFooList);
  print('$jsonText');
  //--- Decode
  List<dynamic> jsonDecodedList = jsonDecode(jsonText);
  print('$jsonDecodedList');
  List<List<Foo>> targetList = [];
  jsonDecodedList.forEach((element) {
    List<dynamic> innerList = element;
    List<Foo> innerTarget = [];
    targetList.add(innerTarget);
    innerList.forEach((innerElement) {
      print('innerElement type=${innerElement.runtimeType}');
      Foo foo = Foo()..fillFromMap(jsonDecode(innerElement));
      innerTarget.add(foo);
    });
  });
  print('$targetList');
}
Jemolah
  • 1,962
  • 3
  • 24
  • 41
0

You have to pass data of nestedFooList and it will return a String.

where nestedFooList should be a instance of List<List< Foo>>

String fooToJson(List<List<Foo>> data) => json.encode(List<dynamic>.from(data.map((x) => List<dynamic>.from(x.map((x) => x.toJson())))));

please try with this, it may solve your issue

Mimu Saha Tishan
  • 2,402
  • 1
  • 21
  • 40