从另一个JSON对象中提取内部JSON对象

时间:2018-04-12 02:42:59

标签: json api twitter dart flutter

我试图使用fromJson工厂使用Twitter API显示推文列表。

每个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对象?

3 个答案:

答案 0 :(得分:1)

Dart不知道你的JSON结构会对应你的对象,或者如何对应。你不能直接为你的对象强制转换JSON(可能是Map<String, dynamic>,但也可能是其他东西)。 @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

答案 1 :(得分:0)

您的json参数为Map<String, dynamic>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),
    );
  }

答案 2 :(得分:0)

在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