Below is the code I use to parse Firestore data (the commented sections are the original way I was parsing nested lists). Normally, I use map
and .toList()
with success, but after I started using abstract and concrete classes, the .toList()
kept throwing errors. I discovered List.from
worked, but I don't understand why. If anyone can help me understand the difference between the two and advice on when to use them, I would greatly appreciate any knowledge you can share.
factory Story.fromMap(Map data) {
if (data == null) {
throw FormatException("Null JSON provided to Story class");
}
try {
return Story(
title: data['title'] ?? '',
type: data['type'] ?? 'standard',
audioRef: data['audioRef'] == null ? null : TourAsset(data['audioRef']),
videoRef: TourAsset(data['videoRef']),
animationRef: TourAsset(data['animationRef']),
posterImgRef: TourAsset(data['posterImgRef']),
storyImages: data["storyImages"] == null
? null
: List<StoryImage>.from(
data["storyImages"].map(
(x) => StoryImage.fromMap(x),
),
),
// storyImages: data['storyImages'] == null
// ? null
// : data['storyImages']
// .map(
// (Map<String, dynamic> eachImage) =>
// StoryImage.fromMap(eachImage),
// )
// .toList(),
ownerId: data['ownerId'] ?? '',
storyId: data['storyId'] ?? '',
tags: data["tags"] == null
? null
: List<String>.from(
data["tags"].map((x) => x),
),
// tags: data['tags'] == null
// ? [] as List<String>
// : data['tags'].map((item) => item as String).toList(),
);
} catch (e) {
print(e);
throw FormatException("Error parsing Story class");
}
}
Below is another attempt that was successful. In it, I assigned storyImages to a local variable and did a null check before mapping over the list.
factory Story.fromMap(Map data) {
if (data == null) {
throw FormatException("Null JSON provided to Story class");
}
try {
final storyImages = data["storyImages"];
final List<StoryImage> storyImagesList = [];
if (storyImages != null) {
for (var story in storyImages) {
storyImagesList.add(StoryImage.fromMap(story));
}
}
return Story(
title: data['title'] ?? '',
type: data['type'] ?? 'standard',
audioRef: data['audioRef'] == null ? null : TourAsset(data['audioRef']),
videoRef: TourAsset(data['videoRef']),
animationRef: TourAsset(data['animationRef']),
posterImgRef: TourAsset(data['posterImgRef']),
storyImages: storyImagesList,
ownerId: data['ownerId'] ?? '',
storyId: data['storyId'] ?? '',
tags: data["tags"] == null
? null
: List<String>.from(data["tags"].map((x) => x)),
);
} catch (e) {
print(e);
throw FormatException("Error parsing Story class");
}
}