Flutter - Как разобрать вложенные структуры JSON со списками во флаттере? - PullRequest
0 голосов
/ 08 июля 2020

Вот мой JSON

{
  "type-1":[
    {
      "name": "type-1-1"
    },
    {
      "name": "type-1-2"
    }
  ],
  "type-2": [
    {
      "name": "type-2-1"
    },
    {
      "name": "type-2-2"
    },
    {
      "name": "type-2-3"
    }
  ]
}

Я хочу проанализировать это JSON, поэтому для этого я написал свою модель вот так

class Places {
  final List<PlaceName> names;
  Places({this.names});

  factory Places.fromJson(Map<String, dynamic> parsedJson){
    var list = parsedJson['name'] as List;
    List<PlaceName> placeList = list.map((i) => PlaceName.fromJson(i)).toList();
    return Places(
        names: placeList
    );
  }
}


class PlaceName {
  final String name;
  PlaceName({this.name});
  factory PlaceName.fromJson(Map<String, dynamic> parsedJson){
    return PlaceName(
        name : parsedJson['name'],
    );
  }
}

и, наконец, у меня есть написал мою функцию в дереве виджетов, как это

Future<String> _loadAllPlaces() async {
    return await rootBundle.loadString('assets/location.json');
  }

  Future loadPlaces() async {
    String jsonString = await _loadAllPlaces();
    final jsonResponse = json.decode(jsonString);
    PlaceName place = new PlaceName.fromJson(jsonResponse);
    print(place);
    print(place.name);
    return place;
  }

Итак, когда я вызываю loadPlaces() в FutureBuilder, он возвращает null. Я попытался отладить его, но безуспешно. Пожалуйста помоги. Заранее спасибо.

1 Ответ

2 голосов
/ 08 июля 2020

В вашем методе Places.fromJson в строке var list = parsedJson['name'] вы пытаетесь получить доступ к списку внутри объектов, прежде чем ссылаться на сам объект. Вместо этого вы должны передать имя одного из объектов, например type-1, например, таким образом var list = parsedJson['type-1'] as List;.

Но это вернет только первый список объектов. Чтобы получить все объекты и список имен каждого из них, вам нужно перебрать объекты json, которыми в этом примере являются type-1 и type-2, а затем перебрать их списки. Вы можете проверить итерацию в AllPlaces.fromJson. Поэтому вам нужно внести некоторые изменения в свой код, чтобы получить все объекты из json. Вы можете попробовать что-то вроде приведенного ниже кода, который можно протестировать на DartPad

import 'dart:convert';

String jsonString = '{"type-1":[{"name": "type-1-1"},{"name": "type-1-2"}],"type-2": [{"name": "type-2-1"},{"name": "type-2-2"},{"name": "type-2-3"}]}';


class AllPlaces {
  List<PlaceName> placeNames;

  AllPlaces({this.placeNames});

  AllPlaces.fromJson(Map<String, dynamic> json) {
    placeNames = new List<PlaceName>();
    //Iterates over the json objects.
     json.forEach((type, list) {
      //Iterates over the list of each object.
      json[type].forEach((list) {
        //Creates an instance of PlaceName and adds to the placeNames list.
        placeNames.add(new PlaceName.fromJson(list));
      });
    });
  }
}

class PlaceName {
  String name;

  PlaceName({this.name});

  PlaceName.fromJson(Map<String, dynamic> json) {
    name = json['name'];
  }

}

Future loadPlaces() async {
   //String jsonString = await _loadAllPlaces();
   final jsonResponse = json.decode(jsonString);
   AllPlaces allPlaces = new AllPlaces.fromJson(jsonResponse);
  
   //Print the names of each object in the console
   allPlaces.placeNames.forEach((place) => print(place.name));
   
   return allPlaces;
}


void main() {
  loadPlaces();
}
...