Анализ ответа / флаттера массива json

#json #flutter #parsing #mapping

Вопрос:

Сделал это в соответствии с данным руководством https://www.bezkoder.com/dart-flutter-parse-json-string-array-to-object-list/Dart/Flutter
проанализируйте массив объектов JSON в список

JSON, который поступает с сервера

{«myChannels»:[{«id»:»2″,»name»:»channel2test»,»imageUrl»:»image1.png»},{«id»:»2″,»name»:»channel2test»,»imageUrl»:»image2.png»}]}

Класс Модели

 class ChannelModel {
  String channelID;
  String channelName;
  String imageUrl;
  ChannelModel(this.channelID, this.channelName, this.imageUrl);

  factory ChannelModel.parsingChannels(dynamic json) {
    return ChannelModel(json['channelID'] as String,
        json['channelName'] as String, json['imageUrl'] as String);
  }
  @override
  String toString() {
    return '{ ${this.channelID}, ${this.channelName}, ${this.imageUrl} }';
  }
}
 

Основной блок

     try {
      final response = await http.post(
        url,
        body: json.encode({
          'action': 'getMyChannels',
          'userID': userID,
          'returnSecureToken': true,
        }),
      );
      //  print(jsonDecode(response.body));

      var extractedData =
          jsonDecode(response.body)['myChannels'] as List<dynamic>;
      List<ChannelModel> channelObjects = extractedData
          .map((cJson) => ChannelModel.parsingChannels(cJson))
          .toList();

      print(channelObjects);
   
      channelObjects.forEach((Data) {
        print('test');           
      });
 

результаты таковы…

 print(channelObjects) > outputs > []
print('test') > not working , channelObjects not looping 
 

Ответ №1:

Я бы предложил сериализовать ваш ответ на dart классы. Было бы намного проще получить доступ к нужным вам данным.

 class ApiResponse {
  ApiResponse({
    required this.myChannels,
  });

  List<MyChannel> myChannels;

  factory ApiResponse.fromJson(Map<String, dynamic> json) => ApiResponse(
        myChannels: List<MyChannel>.from(
          json["myChannels"].map((x) => MyChannel.fromJson(x)),
        ),
      );
}

class MyChannel {
  MyChannel({
    required this.id,
    required this.name,
    required this.imageUrl,
  });

  String id;
  String name;
  String imageUrl;

  factory MyChannel.fromJson(Map<String, dynamic> json) => MyChannel(
        id: json["id"],
        name: json["name"],
        imageUrl: json["imageUrl"],
      );
}
 

Тогда вы можете использовать его таким образом :

 final extractedData = ApiResponse.fromJson(json.decode(response.body) as Map<String, dynamic>);
 

И получите доступ к нужным вам данным

 extractedData.myChannels[0].id
extractedData.myChannels[0].name
extractedData.myChannels[0].imageUrl

for (var ch in extractedData.myChannels){
 print(ch.id);
 print(ch.name);
 print(ch.imageUrl);
}
 

Комментарии:

1. Мне нравится ваш подход, но я не смог решить свою проблему с ним, не знаю почему, тогда я потратил немного больше времени , нашел статью с примером и обновил свой код в соответствии с этой статьей. Но опять же это не работает, не могли бы вы проверить мой код, пожалуйста, и сказать, что вы думаете ?

Ответ №2:

 part 'example.g.dart';

@JsonSerializable()
class Channel{
  final String id;
  final String name;
  final String? imageUrl;
  Channel({required this.id, required this.name, this.imageUrl});
  factory Channel.fromJson(Map<String, dynamic> json) => _$ChannelFromJson(json);
  Map<String, dynamic> toJson() => _$ChannelToJson(this);
}



@JsonSerializable()
class ChannelList{
  final List<Channel> myChannels;
  ChannelList({required this.myChannels});
  factory ChannelList.fromJson(Map<String, dynamic> json) => _$ChannelListFromJson(json);
  Map<String, dynamic> toJson() => _$ChannelListToJson(this);
}
 

окончательные извлеченные данные = channelList.FromJSON(json.decode(response.body));

https://pub.dev/packages/json_serializable

Использование JsonSerializable более полезно и понятно. Вы можете прочитать документацию по этому пакету