Flutter解析JSON时抛出‘type 'Null' is not a subtype of type 'String'’异常排查
问题描述
在Flutter中尝试获取用户列表接口数据并格式化JSON时,抛出异常:type 'Null' is not a subtype of type 'String'。
以下是相关代码:
user_model.dart
class User { int id; String email; String firstName; String lastName; String avator; User({ required this.id, required this.email, required this.firstName, required this.lastName, required this.avator }); factory User.fromJson(Map<String, dynamic> json) => User( id : json['id'], email : json['email'], firstName : json['first_name'], lastName : json['last_name'], avator : json['avator'] ); }
user_api.dart
... class UserApi { Future<List<User>?> getUsers() async { final url = Uri.parse('https://reqres.in/api/users?page=2'); try { final res = await http.get(url); if (res.statusCode == 200) { final Map<String, dynamic> body = jsonDecode(res.body); final List<User> users = body['data'].map((dynamic userData) => { print('userData : $userData'); User.fromJson(userData) // There seems to be an error here. }).toList(); return users; } else { return null; } } catch (e) { print(e.toString()); } return null; } }
控制台输出的userData内容:
flutter: userData : {id: 7, email: michael.lawson@reqres.in, first_name: Michael, last_name: Lawson, avatar: https://reqres.in/img/faces/7-image.jpg}
明明userData不为Null,为何会触发该异常?
问题原因及解决方案
1. 字段名拼写错误(核心原因)
观察控制台输出的userData,头像字段的键是avatar,但你的User模型类中字段名写成了avator,并且在fromJson方法中尝试获取json['avator']——这个键在返回的JSON中不存在,所以会返回null。而你的User类中avator是required的非空String类型,将null赋值给非空字符串就会触发type 'Null' is not a subtype of type 'String'异常。
2. Map转换语法错误
在body['data'].map(...)中,你使用了大括号{}包裹代码,这会让闭包返回一个Map对象而非User实例,导致后续toList()得到的是List<Map>而非List<User>,同样会引发类型错误。
修正后的代码
修正后的user_model.dart
class User { int id; String email; String firstName; String lastName; String avatar; // 修正字段名拼写 User({ required this.id, required this.email, required this.firstName, required this.lastName, required this.avatar // 修正构造函数参数 }); factory User.fromJson(Map<String, dynamic> json) => User( id: json['id'], email: json['email'], firstName: json['first_name'], lastName: json['last_name'], avatar: json['avatar'] // 修正JSON键名 ); }
修正后的user_api.dart
... class UserApi { Future<List<User>?> getUsers() async { final url = Uri.parse('https://reqres.in/api/users?page=2'); try { final res = await http.get(url); if (res.statusCode == 200) { final Map<String, dynamic> body = jsonDecode(res.body); // 去掉大括号,指定泛型<User>确保类型安全 final List<User> users = body['data'].map<User>((dynamic userData) => User.fromJson(userData) ).toList(); return users; } else { return null; } } catch (e) { print(e.toString()); } return null; } }
内容的提问来源于stack exchange,提问作者Nao COMATSU
相关产品推荐
相关产品推荐

