Dart/Flutter JSON转类映射失败,FutureBuilder无数据
Flutter FutureBuilder无数据问题排查与解决
在Flutter项目中使用FutureBuilder时遇到无数据返回的问题,经过排查定位到LUKETXT字段映射错误,具体细节如下:
后端数据获取函数
Future<List<OrderReceipt>> getOrderReceipt(orderno) async { final response = await HttpService.order_receipt(orderno); var decoded = json.decode(response.body)["qry"].cast<Map<String,dynamic>>(); print(decoded); var OrderR = await decoded.map<OrderReceipt>((json) => OrderReceipt.fromJson(json)).toList(); return OrderR; }
自定义类及JSON映射方法
class OrderReceipt { final String LUKEBLART; final String LUKEBLOART; final String LUKEBLONR; final String LUKEBLVC; final String LUKEBLBNR; final String LUKEBLDRAKT; final String LUKEBLADS; final String LUKEBLDATUM; final String LUKEBLPGM; final String LUKETIME; final String LUKESART; final String LUKEPAGE; final String LUKELINE; final String LUKELNR; final String LUKETXT; OrderReceipt({ required this.LUKEBLART, required this.LUKEBLOART, required this.LUKEBLONR, required this.LUKEBLVC, required this.LUKEBLBNR, required this.LUKEBLDRAKT, required this.LUKEBLADS, required this.LUKEBLDATUM, required this.LUKEBLPGM, required this.LUKETIME, required this.LUKESART, required this.LUKEPAGE, required this.LUKELINE, required this.LUKELNR, required this.LUKETXT, }); factory OrderReceipt.fromJson(Map<String, dynamic> json) { return OrderReceipt( LUKEBLART: json['LUKEBLART'] as String ?? '', LUKEBLOART: json['LUKEBLOART'] as String ?? '', LUKEBLONR: json['LUKEBLONR'] as String ?? '', LUKEBLVC: json['LUKEBLVC'] as String ?? '', LUKEBLBNR: json['LUKEBLBNR'] as String ?? '', LUKEBLDRAKT: json['LUKEBLDRAKT'] as String ?? '', LUKEBLADS: json['LUKEBLADS'] as String ?? '', LUKEBLDATUM: json['LUKEBLDATUM'] as String ?? '', LUKEBLPGM: json['LUKEBLPGM'] as String ?? '', LUKETIME: json['LUKETIME'] as String ?? '', LUKESART: json['LUKESART'] as String ?? '', LUKEPAGE: json['LUKEPAGE'] as String ?? '', LUKELINE: json['LUKELINE'] as String ?? '', LUKELNR: json['LUKELNR'] as String ?? '', LUKETXT: json['LUKETX'] as String ?? '', );} }
JSON数据示例(单条)
[{ "LUKEBLADS": "222222", "LUKEBLART": "W ", "LUKEBLBNR": "333333", "LUKEBLDATUM": "20230113", "LUKEBLDRAKT": "FX ", "LUKEBLOART": "FX ", "LUKEBLONR": "4444", "LUKEBLPGM": "XXXKG ", "LUKEBLVC": "X1 ", "LUKELINE": "41", "LUKELNR": "36", "LUKEPAGE": "1", "LUKESART": "1", "LUKETIME": "Fri, 13 Jan 2023 09:54:02 GMT", "LUKETXT": " ExampleText USD 66,20 " }]
问题表现
getOrderReceipt函数能正常打印解码后的decoded数据,但无法完成映射返回OrderReceipt列表- FutureBuilder处理后无数据返回,且无任何报错提示
- 项目中其他两个FutureBuilder功能正常
排查过程
- 移除
.cast<Map<String,dynamic>>()和await后,问题依旧存在 - 添加try-catch捕获到错误:
type 'null' is not a subtype of type 'string' in type cast - 注释模型中的
LUKETXT字段后,功能恢复正常
错误原因及解决方法
错误原因
在OrderReceipt.fromJson工厂方法中,LUKETXT字段的映射使用了错误的键名:json['LUKETX'],而JSON数据中的实际键名是LUKETXT(少了一个字母T),导致获取到null,执行as String类型转换时抛出类型不匹配错误,最终导致整个列表映射失败,FutureBuilder无数据返回。
解决方法
将工厂方法中LUKETXT的映射代码修改为正确的键名:
LUKETXT: json['LUKETXT'] as String ?? '',
同时,建议优化类型转换的安全性,避免直接使用as String导致崩溃,可以改用更稳妥的写法:
LUKETXT: (json['LUKETXT'] ?? '').toString(),
内容的提问来源于stack exchange,提问作者Lukas Fürst
相关产品推荐
相关产品推荐

