Flutter中GET请求API遇Null转Map类型错误求助
问题排查:
type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast 错误信息
"Error: type 'Null' is not a subtype of type 'Map<String, dynamic>' in type cast"
错误原因分析
- API返回结构不符预期:虽然请求返回状态码200,但实际返回的JSON中,
data或user字段为null,而你的模型类(UserModel/UserData)将这些字段定义为必填非空类型,json_serializable在强制类型转换时触发错误。 - 缺少响应校验:请求层未对返回的JSON结构做前置校验,直接进入模型转换流程,导致空值被强制转为Map类型。
解决方案步骤
1. 先确认API实际返回内容
在API请求代码中添加响应体打印,明确返回的JSON结构:
class MyProfileApiServices { final String myProfileUrl = 'https://bigshelf-node-dev.onrender.com/api/v1/users/my-profile'; Future<UserModel> fetchUserData() async { final response = await http.get(Uri.parse(myProfileUrl)); // 新增:打印原始响应体,确认实际返回内容 debugPrint('API原始响应: ${response.body}'); if (response.statusCode == 200) { final jsonResponse = jsonDecode(response.body); // 新增:校验核心字段是否存在且类型正确 if (jsonResponse is Map && jsonResponse['status'] != null && jsonResponse['data'] != null && jsonResponse['data'] is Map) { final userData = UserModel.fromJson(jsonResponse); debugPrint('$userData'); return userData; } else { throw Exception('API返回结构不符合预期'); } } else { debugPrint('请求失败,状态码: ${response.statusCode}'); throw Exception('Failed to load user data'); } } }
2. 修改模型类兼容空值
如果API确实可能返回data或user为null,将对应字段改为可空类型,并更新json_serializable生成代码:
import 'package:json_annotation/json_annotation.dart'; part 'user_model.g.dart'; @JsonSerializable(explicitToJson: true) class UserModel { final String status; final UserData? data; // 改为可空字段 UserModel({ required this.status, this.data, }); factory UserModel.fromJson(Map<String, dynamic> json) => _$UserModelFromJson(json); Map<String, dynamic> toJson() => _$UserModelToJson(this); } @JsonSerializable(explicitToJson: true) class UserData { final User? user; // 改为可空字段 final int? followersCount; final int? followingCount; UserData({ this.user, this.followersCount, this.followingCount, }); factory UserData.fromJson(Map<String, dynamic> json) => _$UserDataFromJson(json); Map<String, dynamic> toJson() => _$UserDataToJson(this); } // 其余User类代码不变,按需调整字段可空性
修改后重新运行flutter pub run build_runner build生成新的序列化代码。
3. 在UI层处理空值情况
在FutureBuilder中增加空值判断,避免空指针:
else if (snapshot.hasData) { final userModel = snapshot.data!; // 校验data和user是否存在 if (userModel.data == null || userModel.data!.user == null) { return const Center(child: Text('用户数据未加载')); } final user = userModel.data!.user!; final followersCount = userModel.data!.followersCount ?? 0; final followingCount = userModel.data!.followingCount ?? 0; // 后续UI渲染代码不变,替换原有的snapshot.data!.data引用 }
额外提示
如果API需要身份验证(比如登录态),检查请求头是否携带了正确的Token,未登录状态下API可能返回空数据或错误结构,这也是常见触发该错误的原因。
内容的提问来源于stack exchange,提问作者Igwe Ugochukwu
相关产品推荐
相关产品推荐

