Flutter获取API数据时遇类型不匹配异常,求解决方案
问题分析与解决方案
错误原因
你遇到的异常 type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable' 是因为在 getData() 函数中,你尝试直接遍历API返回的整个JSON对象(它是一个Map,而非可迭代的列表)。API返回的结构是一个包含data数组的单对象,而非UserModel的列表,你的遍历逻辑完全错误。
同时,你对数据模型的使用也存在混淆:UserModel本身已经包含了用户数据列表data,不需要将其包装成List<UserModel>。
具体修复步骤
1. 修正getData()函数
将返回类型改为Future<UserModel>,直接解析整个API响应为单个UserModel实例:
Future<UserModel> getData() async { final response = await http.get(Uri.parse('https://reqres.in/api/users?page=2')); if (response.statusCode == 200) { return UserModel.fromJson(jsonDecode(response.body)); } else { throw Exception('Failed to load user data'); } }
2. 调整状态变量与初始化
移除多余的userModelList,使用已定义的futureUser变量存储API请求结果,并在initState中初始化:
class _FirstScreenState extends State<FirstScreen> { Future<UserModel>? futureUser; TextEditingController textController = TextEditingController(); @override void initState() { futureUser = getData(); super.initState(); } // 移除原来的userModelList和错误的getData函数,替换为上面修正后的版本 }
3. 修正FutureBuilder与ListView逻辑
使用futureUser作为FutureBuilder的数据源,直接从UserModel的data属性获取用户列表:
Expanded( child: FutureBuilder<UserModel>( future: futureUser, builder: (context, snapshot) { if (snapshot.hasData) { final userList = snapshot.data!.data!; return ListView.builder( itemCount: userList.length, shrinkWrap: true, itemBuilder: (context, index) { final user = userList[index]; return Padding( padding: EdgeInsets.all(10), child: Column( children: [ InkWell( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => ProfilePage( userName: user.firstName ?? '', followers: user.id.toString() ?? 'N/A', address: user.email ?? '', following: user.lastName, imageUrl: user.avatar ?? 'N/A', ), ), ); }, child: ListTileWidgets( following: user.lastName, address: user.email ?? '', imageUrl: user.avatar ?? 'N/A', name: user.firstName ?? '', followersCount: 'Followers: ${user.id}', iconWidget: Icon( Icons.person_add_alt_outlined, color: Colors.red, size: 25, ), ), ), AppLine( paddingLeft: 10, paddingRight: 10, heightLine: 1, lineColor: Colors.grey), ], ), ); }, ); } else if (snapshot.hasError) { return Text('${snapshot.error}'); } return Center(child: CircularProgressIndicator()); }, ), )
关键说明
- API响应结构:
https://reqres.in/api/users?page=2返回的是一个包含page、total、data等字段的JSON对象,其中data才是用户列表数组,你的UserModel已经正确处理了这个结构。 - 避免重复请求:将
futureUser在initState中初始化,而不是直接在FutureBuilder中调用getData(),可以防止每次Widget重建时重复发起API请求。 - 数据访问逻辑:直接从
snapshot.data!.data!获取用户列表,避免了原代码中错误的双层索引(userModelList[index].data![index])导致的逻辑混乱。
内容的提问来源于stack exchange,提问作者Md. Fazle Rabbi
相关产品推荐
相关产品推荐

