Extracting an internal JSON object from another JSON object
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.
argamanza
Updated on December 04, 2022Comments
-
argamanza over 1 year
I'm trying to show a list of tweets using Twitter API, using the
fromJson
factory.Each
tweet
object has anextended_entities
object which is an array ofmedia
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 themedia
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? -
Dan Field about 6 yearsOP also has to do something similar in
TweetExtendedEntities.fromJson
- can't cast it directly to aList<TweetMedia>
. This answer would be a bit more helpful if it at least pointed out how that might work