Flutter API JSON映射报错:List<dynamic>无法转为String求助
JSON转Model时类型不匹配错误解决方案
问题概述
调用API时,单独读取响应中的单个值功能正常,但将JSON映射到MovieLists数据模型时失败,调试控制台报错:type 'List<dynamic>' is not a subtype of type 'String'。
错误日志
E/flutter ( 4602): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'String' E/flutter ( 4602): #0 new MovieLists.fromMapJson (package:movie_app_1/data/models/movies_list_model.dart:29:20) E/flutter ( 4602): #1 getDada.<anonymous closure> (package:movie_app_1/screens/splashScreen.dart:44:54) E/flutter ( 4602): #2 MappedListIterable.elementAt (dart:_internal/iterable.dart:415:31) E/flutter ( 4602): #3 ListIterator.moveNext (dart:_internal/iterable.dart:344:26) E/flutter ( 4602): #4 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:189:2
相关代码
API请求代码
Future<void> getDada(context) async { var response = await Dio().get('*****'); List<MovieLists> moviesList = response.data['data'] .map<MovieLists>((jsonMapObject) => MovieLists.fromMapJson(jsonMapObject)) .toList(); print('---------------> ${moviesList.length}'); Navigator.push( context, MaterialPageRoute( builder: (context) => homeScreen(listMovies: moviesList), ), ); }
MovieLists数据模型
class MovieLists { int id; String title; String poster; String year; String country; String imdbRating; String genres; String images; MovieLists( this.id, this.title, this.poster, this.year, this.country, this.imdbRating, this.genres, this.images, ); factory MovieLists.fromMapJson(Map<String, dynamic> jsonMapObject) { return MovieLists( jsonMapObject['id'], jsonMapObject['title'], jsonMapObject['poster'], jsonMapObject['year'], jsonMapObject['country'], jsonMapObject['imdb_rating'], jsonMapObject['genres'], jsonMapObject['images'], ); } }
问题原因
API返回的JSON中,genres或images字段是数组类型(比如["动作", "喜剧"]),但MovieLists模型中把这两个字段定义成了String类型,导致类型转换失败。
解决方案
根据需求选择以下两种修改方式:
方式1:将字段类型改为数组(推荐,保留原始数据结构)
修改MovieLists类,把genres和images的类型改为List<String>,并在fromMapJson中处理类型转换和空值:
class MovieLists { int id; String title; String poster; String year; String country; String imdbRating; List<String> genres; List<String> images; MovieLists( this.id, this.title, this.poster, this.year, this.country, this.imdbRating, this.genres, this.images, ); factory MovieLists.fromMapJson(Map<String, dynamic> jsonMapObject) { return MovieLists( jsonMapObject['id'] as int, jsonMapObject['title'] as String, jsonMapObject['poster'] as String, jsonMapObject['year'] as String, jsonMapObject['country'] as String, jsonMapObject['imdb_rating'] as String, // 处理数组转List<String>,空值时返回空列表 List<String>.from(jsonMapObject['genres'] ?? []), List<String>.from(jsonMapObject['images'] ?? []), ); } }
方式2:将数组转为字符串(适合需要展示为单一字符串的场景)
如果需要把数组转为逗号分隔的字符串,修改fromMapJson中的对应字段处理逻辑:
class MovieLists { int id; String title; String poster; String year; String country; String imdbRating; String genres; String images; MovieLists( this.id, this.title, this.poster, this.year, this.country, this.imdbRating, this.genres, this.images, ); factory MovieLists.fromMapJson(Map<String, dynamic> jsonMapObject) { return MovieLists( jsonMapObject['id'] as int, jsonMapObject['title'] as String, jsonMapObject['poster'] as String, jsonMapObject['year'] as String, jsonMapObject['country'] as String, jsonMapObject['imdb_rating'] as String, // 将数组转为逗号分隔的字符串,空值时返回空字符串 (jsonMapObject['genres'] as List?)?.join(', ') ?? '', (jsonMapObject['images'] as List?)?.join(', ') ?? '', ); } }
额外优化建议
- 为所有字段添加显式类型转换(
as int/as String),避免隐式类型转换带来的潜在问题。 - 处理API返回的空值情况(比如
??运算符),防止空指针异常。
内容的提问来源于stack exchange,提问作者Parsa
相关产品推荐
相关产品推荐

