skip to Main Content

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


  1. 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),
        );
      }
    
    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
  3. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search