1

I'm trying to show a list of tweets using Twitter API, using the fromJson factory.

Each tweet object has an extended_entities object which is an array of media objects.

If you're not familiar with the Twitter API you can see all the different objects here.

Here are the models i created in order to achieve this:

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,
    );
  }
}

Before i tried to get the extended_entities object everything was fine and i successfully got the JSON data and parsed it, but when i try to get the media objects using the code above, i get this error:

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

How can i get nested JSON objects using factory or any other way?

3 Answers 3

1

Dart has no idea that your JSON structure will correspond to your object, or how. You can't directly cast the JSON (which is probably a Map<String, dynamic>, but could also be other things) to your objects. @betorcs answer is a start in the right direction but needs a bit more.

This line:

tweetExtendedEntities: json['extended_entities'] as TweetExtendedEntities,

Needs to be

tweetExtendedEntities: TweetExtendedEntities.fromJson['extended_entities'],

And your TweetExtendedEntities method should look more like this:

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();
}

You could also certainly look into json_serializable if your needs start getting more complicated and you want to try to generate some of this code.

Sign up to request clarification or add additional context in comments.

Comments

0

Your json parameter is Map<String, dynamic>, dynamic is not TweetExtendedEntities, but it can be cast to 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),
    );
  }

1 Comment

OP also has to do something similar in TweetExtendedEntities.fromJson - can't cast it directly to a List<TweetMedia>. This answer would be a bit more helpful if it at least pointed out how that might work
0

In flutter, this error will be thrown when you pass a string without json.decode() to the fromjson factory

eg:

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

The LoginResponse class

class LoginResponse {
  int responseCode;
  String message;
  String responseObject;

  LoginResponse();

  factory LoginResponse.fromJson(Map<String, dynamic> json) => _$LoginResponseFromJson(json);
}

JSON and serialization in Flutter

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.