The Vinh Luong
The Vinh Luong

Reputation: 1193

Parse a JSON array with multiple object types

Let's say I have a JSON array like this:

"videos": [
      {
        "id": 25182,
        "game": 115653,
        "name": "Trailer",
        "video_id": "BdA22Lh6Rwk"
      },
      27749,
      {
        "id": 29188,
        "game": 115653,
        "name": "A New Team and New Rivals in Pokémon Sword and Pokémon Shield! ⚔️🛡️",
        "video_id": "ZBiTpi8ecTE"
      }
    ]

Normally if the item's JSON format in videos is like videos[0] or videos[2] then I was able to parse it to Video like this:

json['videos']?.cast<Map<String, dynamic>>()?.map<Video>((f) {
        return Video.fromJson(f);
    })?.toList();

My Video class:

class Video {
  int id;
  int game;
  String name;
  String videoId;

  Video({this.id, this.game, this.name, this.videoId});

  Video.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    game = json['game'];
    name = json['name'];
    videoId = json['video_id'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['id'] = this.id;
    data['game'] = this.game;
    data['name'] = this.name;
    data['video_id'] = this.videoId;
    return data;
  }
}

But if something with the different structure like videos[1] is within the array then I ended up with Exception. How can I parse videos[1] to Video with video[1] as Video's id?

Upvotes: 0

Views: 1413

Answers (1)

lrn
lrn

Reputation: 71828

You have to know the different formats and figure out which one each entry is. You can do that by checking the type of the entry: Is it an integer or a map?

Example:

List<Video> videosFromJson(List<Object> videoJson) {
  var result = <Video>[];
  for (int i = 0; i < videoJson.length; i++) {
    var entry = videoJson[i];
    if (entry is Map<String, dynamic>) {
      result.add(Video.fromJson(entry));
    } else if (entry is int) {
      result.add(Video()..id = entry);
    } else {
      throw FormatException("Not a recognized video format", entry, i);
    }
  }
  return result;
}

Upvotes: 1

Related Questions