I'm trying to get some images from an API but facing this error
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'String' is not a subtype of type 'Map<dynamic, dynamic>'
The Json from the API looks like this and it's from www.themoviedb.org:
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/qxeqKcVBWnQxUp1w6fwWcxZEA6m.jpg",
"genre_ids": [
28,
12,
14
],
"id": 436270,
"original_language": "en",
"original_title": "Black Adam",
"overview": "Nearly 5,000 years after he was bestowed with the almighty powers of the Egyptian gods—and imprisoned just as quickly—Black Adam is freed from his earthly tomb, ready to unleash his unique form of justice on the modern world.",
"popularity": 6041.545,
"poster_path": "/3zXceNTtyj5FLjwQXuPvLYK5YYL.jpg",
"release_date": "2022-10-19",
"title": "Black Adam",
"video": false,
"vote_average": 7.2,
"vote_count": 425
},
],
"total_pages": 35601,
"total_results": 712013
}
Here is the code:
Movie
class Movie {
final int id;
final String name;
final String description;
final String? posterPath;
//<editor-fold desc="Data Methods">
Movie({
required this.id,
required this.name,
required this.description,
this.posterPath,
});
Movie copyWith({
int? id,
String? name,
String? description,
String? posterPath,
}) {
return Movie(
id: id ?? this.id,
name: name ?? this.name,
description: description ?? this.description,
posterPath: posterPath ?? this.posterPath,
);
}
factory Movie.fromJson(Map<String, dynamic> map) {
return Movie(
id: map['id'] as int,
name: map['title'] as String,
description: map['overview'] as String,
posterPath: map['poster_path'] as String,
);
}
// Poster url ****************************************************************
String posterUrl() {
Api api = Api();
return api.baseUrl + posterPath!;
}
//</editor-fold>
}
API
class Api {
final String apiKey = ApiKey.apiKey;
final String baseUrl = "https://developers.themoviedb.org/3";
final String baseImageUrl = "https://image.tmdb.org/t/p/w500/";
final String baseVideoUrl = "https://www.youtube.com/watch?=v";
}
ApiKey
class ApiKey {
static String apiKey = "my_api_key";
}
ApiService
class ApiService {
final Api api = Api();
final Dio dio = Dio();
Future<Response> getData(String path, {Map<String, dynamic>? params}) async {
String url = api.baseUrl + path;
Map<String, dynamic> query = {
"api_key": api.apiKey,
"language": "en-US",
};
if(params != null) {
query.addAll(params);
}
final response = await dio.get(url, queryParameters: query);
if(response.statusCode == 200) {
return response;
}
else {
throw response;
}
}
//****************************************************************************
// Get popular movies
//****************************************************************************
Future getPopularMovies({required int pageNumber}) async{
Response response = await getData(
"/movie/popular",
params: {
"page": pageNumber,
}
);
if(response.statusCode == 200){
Map data = response.data; // <--------------------------- Problem is here
List<dynamic> results = data["results"]; // <--------------------------- And here
List<Movie> movies = [];
for(Map<String, dynamic> json in results){
Movie movie = Movie.fromJson(json);
movies.add(movie);
}
return movies;
}
else{
throw response;
}
}
}
HomeScreen
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<Movie>? movies;
@override
void initState() {
super.initState();
getMovies();
}
//****************************************************************************
// Get movies
//****************************************************************************
void getMovies(){
ApiService().getPopularMovies(pageNumber: 1)
.then((movieList){
setState(() {
movies = movieList;
});
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kBackgroundColor,
appBar: AppBar(
backgroundColor: kBackgroundColor,
leading: Image.asset(
"assets/images/netflix_logo_2.png"
),
),
body: ListView(
children: [
Container(
height: 500,
color: Colors.red,
child: movies == null
? const Center()
: Image.network(
movies![0].posterUrl(),
fit: BoxFit.cover,
),
),
const SizedBox(height: 15,),
Text("Current trends",
style: GoogleFonts.poppins(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5,),
SizedBox(
height: 160,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 110,
margin: const EdgeInsets.only(right: 8),
color: Colors.yellow,
child: Center(
child: Text(index.toString()),
),
);
},
),
),
const SizedBox(height: 15,),
Text("Currently in cinema",
style: GoogleFonts.poppins(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5,),
SizedBox(
height: 320,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 220,
margin: const EdgeInsets.only(right: 8),
color: Colors.blue,
child: Center(
child: Text(index.toString()),
),
);
},
),
),
const SizedBox(height: 15,),
Text("Available soon",
style: GoogleFonts.poppins(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold
),
),
const SizedBox(height: 5,),
SizedBox(
height: 160,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: 10,
itemBuilder: (context, index) {
return Container(
width: 110,
margin: const EdgeInsets.only(right: 8),
color: Colors.green,
child: Center(
child: Text(index.toString()),
),
);
},
),
),
],
),
);
}
}
What I've tried:
I've tried to replace Map
with var
in ApiService but the problem isn't solved because another error is shown in the logcat doing this:
[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'String' is not a subtype of type 'int' of 'index'
Thanks in advance for the help