`_CastError (type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List?' in type cast)
I am trying to fetch rest api here from jikan My animelist unofficial api.
As you can see i am trying to turn it to a list but i failed and need help it is giving me the error in the top.Please someone make me figure this out`
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late final future = getTopAnime();
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<List<TopAnime>?>(
future: future,
builder: (context, snapshot) {
if (snapshot.hasData) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: 10,
itemBuilder: ((context, index) {
final model = snapshot.data![index].data[index].rank;
final modell = snapshot.data![index].data[index].title;
return Card(
elevation: 20,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20)),
padding: EdgeInsets.all(20),
child: Column(children: [Text(modell), Text("$model")]),
),
);
}));
}
return CircularProgressIndicator();
},
),
);
}
}
Future<List<TopAnime>?> getTopAnime() async {
final response =
await http.get(Uri.parse("https://api.jikan.moe/v4/top/anime"));
if (response.statusCode == 200) {
final data = jsonDecode(response.body) as List?;
return data?.map((e) => TopAnime.fromJson(e)).toList();
} else {
throw Exception("hey");
}
}
TopAnime topAnimeFromJson(String str) => TopAnime.fromJson(json.decode(str));
String topAnimeToJson(TopAnime data) => json.encode(data.toJson());
class TopAnime {
TopAnime({
required this.data,
required this.pagination,
});
List<Datum> data;
Pagination pagination;
factory TopAnime.fromJson(Map<String, dynamic> json) => TopAnime(
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
pagination: Pagination.fromJson(json["pagination"]),
);
Map<String, dynamic> toJson() => {
"data": List<dynamic>.from(data.map((x) => x.toJson())),
"pagination": pagination.toJson(),
};
}
class Datum {
Datum({
required this.malId,
required this.url,
required this.images,
required this.trailer,
required this.approved,
required this.titles,
required this.title,
required this.titleEnglish,
required this.titleJapanese,
required this.titleSynonyms,
required this.type,
required this.source,
required this.episodes,
required this.status,
required this.airing,
required this.aired,
required this.duration,
required this.rating,
required this.score,
required this.scoredBy,
required this.rank,
required this.popularity,
required this.members,
required this.favorites,
required this.synopsis,
required this.background,
required this.season,
required this.year,
required this.broadcast,
required this.producers,
required this.licensors,
required this.studios,
required this.genres,
required this.explicitGenres,
required this.themes,
required this.demographics,
});
int malId;
String url;
Map<String, Image> images;
Trailer trailer;
bool approved;
List<Title> titles;
String title;
String titleEnglish;
String titleJapanese;
List<String> titleSynonyms;
String type;
String source;
int episodes;
String status;
bool airing;
Aired aired;
String duration;
String rating;
int score;
int scoredBy;
int rank;
int popularity;
int members;
int favorites;
String synopsis;
String background;
String season;
int year;
Broadcast broadcast;
List<Demographic> producers;
List<Demographic> licensors;
List<Demographic> studios;
List<Demographic> genres;
List<Demographic> explicitGenres;
List<Demographic> themes;
List<Demographic> demographics;
class Image {
Image({
required this.imageUrl,
required this.smallImageUrl,
required this.largeImageUrl,
});
String imageUrl;
String smallImageUrl;
String largeImageUrl;
factory Image.fromJson(Map<String, dynamic> json) => Image(
imageUrl: json["image_url"],
smallImageUrl: json["small_image_url"],
largeImageUrl: json["large_image_url"],
);
Map<String, dynamic> toJson() => {
"image_url": imageUrl,
"small_image_url": smallImageUrl,
"large_image_url": largeImageUrl,
};
}
CodePudding user response:
Change your getTopAnime()
method like this. The return type is not a List
. It's Map
that contains "data" and "pagination". Here it seems you don't need "pagination" so use only "data" like this.
Future<List<Datum>?> getTopAnime() async {
final response =
await http.get(Uri.parse("https://api.jikan.moe/v4/top/anime"));
if (response.statusCode == 200) {
/// Change these lines
final data = jsonDecode(response.body);
List<dynamic> res = data['data'];
final movies = res.map((dynamic d) => Datum.fromJson(d)).toList();
return movies;
} else {
throw Exception("hey");
}
}
And you can use in your GridView
like this.
itemBuilder: ((context, index) {
final model = snapshot.data![index].rank;
final modell = snapshot.data![index].title;
/// *** your code ***
}
Bonus: I've simplified your code and made what you wanna achieve. Use it as you like.
Code can be found here : https://gist.github.com/YeLwinOo-Steve/d7619f9ea53a75c6bcdb8b074b3e0e2d
And I also suggest you to take a deeper look at Json Serialization and Fetching data from Api.
Here are official resources. Fetching data: https://dart.dev/tutorials/web/fetch-data
Json Serialization: https://docs.flutter.dev/development/data-and-backend/json
Have Fun!