【问题标题】:Extracting an internal JSON object from another JSON object从另一个 JSON 对象中提取内部 JSON 对象
【发布时间】:2018-09-22 01:14:53
【问题描述】:

我正在尝试使用Twitter API 显示推文列表,使用fromJson 工厂。

每个tweet 对象都有一个extended_entities 对象,它是media 对象的数组。

如果您不熟悉Twitter API,您可以看到所有不同的对象here

这是我为实现这一目标而创建的模型:

class Tweet {
  final String createdAt;
  final int id;
  final String idStr;
  final String text;
  final String inReplyToStatusIdStr;
  final String inReplyToUserIdStr;
  final TweetExtendedEntities tweetExtendedEntities;

  Tweet(
      {this.createdAt,
      this.id,
      this.idStr,
      this.text,
      this.inReplyToStatusIdStr,
      this.inReplyToUserIdStr,
      this.tweetExtendedEntities});

  factory Tweet.fromJson(Map<String, dynamic> json) {
    return new Tweet(
      createdAt: json['created_at'] as String,
      id: json['id'] as int,
      idStr: json['id_str'] as String,
      text: json['text'] as String,
      inReplyToStatusIdStr: json['in_reply_to_status_id_str'] as String,
      inReplyToUserIdStr: json['in_reply_to_user_id_str'] as String,
      tweetExtendedEntities: json['extended_entities'] as TweetExtendedEntities,
    );
  }
}

class TweetExtendedEntities {
  final List<TweetMedia> tweetMedia;

  TweetExtendedEntities({this.tweetMedia});

  factory TweetExtendedEntities.fromJson(Map<String, dynamic> json) {
    return new TweetExtendedEntities(
        tweetMedia: json['media'] as List<TweetMedia>);
  }
}

class TweetMedia {
  final String mediaType;
  final String mediaUrl;

  TweetMedia({this.mediaType, this.mediaUrl});

  factory TweetMedia.fromJson(Map<String, dynamic> json) {
    return new TweetMedia(
      mediaType: json['type'] as String,
      mediaUrl: json['media_url'] as String,
    );
  }
}

在我尝试获取 extended_entities 对象之前,一切都很好,我成功获取了 JSON 数据并对其进行了解析,但是当我尝试使用上面的代码获取 media 对象时,我得到了这个错误:

I/flutter (29538): type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'TweetExtendedEntities' in type cast where
I/flutter (29538):   _InternalLinkedHashMap is from dart:collection
I/flutter (29538):   String is from dart:core
I/flutter (29538):   TweetExtendedEntities is from package:pubg_companion/models/tweet.dart

如何使用factory 或任何其他方式获取嵌套的 JSON 对象?

【问题讨论】:

    标签: json api twitter dart flutter


    【解决方案1】:

    Dart 不知道您的 JSON 结构将与您的对象或如何对应。您不能直接将 JSON(可能是 Map&lt;String, dynamic&gt;,但也可能是其他东西)转换为您的对象。 @betorcs 的答案是朝着正确的方向开始,但还需要更多。

    这一行:

    tweetExtendedEntities: json['extended_entities'] as TweetExtendedEntities,
    

    需要

    tweetExtendedEntities: TweetExtendedEntities.fromJson['extended_entities'],
    

    您的TweetExtendedEntities 方法应该看起来更像这样:

    factory TweetExtendedEntities.fromJson(Map<String, dynamic> json) {
      return new TweetExtendedEntities(
          tweetMedia: createTweetMediaList(json['media']));
    }
    
    static List<TweetMedia> createTweetMediaList(List json) {
      if (json == null) return null;
      if (json.isEmpty) return [];
    
      return json.map((tweetMediaJson) => TweetMedia.fromJson(tweetMediaJson)).toList();
    }
    

    如果您的需求开始变得越来越复杂并且您想尝试生成其中的一些代码,您当然也可以查看json_serializable

    【讨论】:

      【解决方案2】:

      你的json参数是Map&lt;String, dynamic&gt;dynamic不是TweetExtendedEntities,但是可以转换成Map

      factory Tweet.fromJson(Map<String, dynamic> json) {
          return new Tweet(
            createdAt: json['created_at'] as String,
            id: json['id'] as int,
            idStr: json['id_str'] as String,
            text: json['text'] as String,
            inReplyToStatusIdStr: json['in_reply_to_status_id_str'] as String,
            inReplyToUserIdStr: json['in_reply_to_user_id_str'] as String,
            tweetExtendedEntities: TweetExtendedEntities.fromJson(json['extended_entities'] as Map),
          );
        }
      

      【讨论】:

      • OP 还必须在 TweetExtendedEntities.fromJson 中执行类似的操作 - 不能将其直接转换为 List&lt;TweetMedia&gt;。如果它至少指出了它的工作原理,这个答案会更有帮助
      【解决方案3】:

      在flutter中,当你将一个没有json.decode()的字符串传递给fromjson工厂时会抛出这个错误

      例如:

      Map bodyJson = json.decode(loginResponse.body);
      var login = new LoginResponse.fromJson(bodyJson);
      

      LoginResponse 类

      class LoginResponse {
        int responseCode;
        String message;
        String responseObject;
      
        LoginResponse();
      
        factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json);
      }
      

      JSON and serialization in Flutter

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-08-29
        • 2019-06-18
        • 2017-08-12
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        相关资源
        最近更新 更多