使用TMDB API获取热门电影第三页时出现类型不匹配错误
TMDB获取热门电影第三页时出现Null转String错误的解决方法
我使用TMDB接口获取电影数据,前两页数据正常,请求第三页热门电影时抛出如下错误:
Exception occured: type 'Null' is not a subtype of type 'String' stackTrace: #0
返回错误的获取数据函数
class DioApiClient implements ApiClient { final Dio dio = Dio(); final Api api = Api(); @override Future<List<MovieModel>> getDataFrom(String endPoint, {Map<String, dynamic>? params}) async { final String url = "${api.baseURL}/$endPoint"; log("from api client :$url/$params"); Map<String, dynamic> queryParameters = { 'api_key': api.apiKey, // 'language': 'en-US', }; if (params != null) { queryParameters.addAll(params); } try { final response = await dio.get(url, queryParameters: queryParameters); log(" status code : ${response.statusCode}"); if (response.statusCode == 200) { final Map<String, dynamic> data = response.data; final List<dynamic> results = data['results']; final List<MovieModel> movies = results.map((dynamic movie) => MovieModel.fromJson(movie)).toList(); return movies; } } catch (error, stacktrace) { log("Exception occured: $error stackTrace: $stacktrace"); throw Exception('Failed to load data '); } throw Exception("data not found"); } }
对应的MovieModel代码
import '../../domain/entities/movie_entity.dart'; class MovieModel { final int id; final String title; final String overview; final String posterPath; final num voteAverage; final String backdropPath; final String releaseDate; MovieModel({ required this.id, required this.title, required this.overview, required this.posterPath, required this.voteAverage, required this.backdropPath, required this.releaseDate, }); factory MovieModel.fromJson(Map<String, dynamic> json) { return MovieModel( id: json['id'], title: json['title'], overview: json['overview'], posterPath: json['poster_path'], voteAverage: json['vote_average'], backdropPath: json['backdrop_path'], releaseDate: json['release_date'], ); } MovieEntity toEntity() { return MovieEntity( id: id, title: title, overview: overview, posterPath: posterPath, voteAverage: voteAverage, backdropPath: backdropPath, releaseDate: releaseDate, ); } }
我曾尝试将backdropPath和posterPath设为可空类型,但问题依旧。从API响应中可以看到,部分电影的backdrop_path、poster_path等字段为null值。
问题原因
错误本质是TMDB返回的JSON中部分字段为null,但MovieModel里对应字段被声明为非空String类型,导致解析时类型不匹配。仅修改backdropPath和posterPath可能不够,其他字段(如overview、release_date)也可能出现null情况,或者你修改可空类型的方式未覆盖所有场景。
解决方案
方案1:将可能为null的字段设为可空,并在解析时兜底默认值
修改MovieModel代码,确保所有可能返回null的字段处理到位:
import '../../domain/entities/movie_entity.dart'; class MovieModel { final int id; final String? title; final String? overview; final String? posterPath; final num voteAverage; final String? backdropPath; final String? releaseDate; MovieModel({ required this.id, this.title, this.overview, this.posterPath, required this.voteAverage, this.backdropPath, this.releaseDate, }); factory MovieModel.fromJson(Map<String, dynamic> json) { return MovieModel( id: json['id'] ?? 0, // 兜底默认ID title: json['title'] ?? '', overview: json['overview'] ?? '', posterPath: json['poster_path'] ?? '', voteAverage: json['vote_average'] ?? 0.0, backdropPath: json['backdrop_path'] ?? '', releaseDate: json['release_date'] ?? '', ); } MovieEntity toEntity() { return MovieEntity( id: id, title: title ?? '', overview: overview ?? '', posterPath: posterPath ?? '', voteAverage: voteAverage, backdropPath: backdropPath ?? '', releaseDate: releaseDate ?? '', ); } }
方案2:保持字段非空,强制给null字段赋默认值
如果不想修改字段可空性,可在fromJson中直接为null字段赋值默认空字符串或默认值:
factory MovieModel.fromJson(Map<String, dynamic> json) { return MovieModel( id: json['id'] ?? 0, title: json['title'] ?? '', overview: json['overview'] ?? '', posterPath: json['poster_path'] ?? '', voteAverage: json['vote_average'] ?? 0.0, backdropPath: json['backdrop_path'] ?? '', releaseDate: json['release_date'] ?? '', ); }
额外检查
确认请求第三页的参数是否正确(如page=3是否正确传递),但从错误类型判断,核心问题还是JSON解析时的null值处理。
内容的提问来源于stack exchange,提问作者Ydev
相关产品推荐
相关产品推荐

