Flutter对比Map(radioValue)与List(answerTable)调用API报错如何解决?
问题修复方案
根因说明
- 报错
Bad state: No element是Dart标准库firstWhere方法的默认行为:当列表中没有匹配条件的元素,且未传入orElse回调时,会直接抛出该异常,而非返回null。 - 你两次编写的代码都存在逻辑错误:
- 第一版嵌套循环逻辑错误:同一个问题ID会遍历整个答案列表,每遇到一个不匹配的答案就会触发一次新增接口调用,会出现重复调用的问题,且答案列表为空时循环不会执行,自然不会触发任何接口。
- 第二版接口调用逻辑写反:匹配到已有答案时应该调用编辑接口,无匹配时才调用新增接口,且你把接口调用逻辑和值是否为空的判断绑定错了。
正确实现
方案1:简单适配,适合答案列表数据量小的场景
直接给firstWhere添加orElse回调处理无匹配的情况:
List<ChecklistAnswerItem> answerTable = await _repository.selectChecklistAnswerItemsList(); for (var key in radioValue.keys) { final answerValue = radioValue[key]; // 空答案直接跳过不处理 if (answerValue == null || answerValue.toString().trim().isEmpty) continue; // 无匹配时返回null final ChecklistAnswerItem? matchedItem = answerTable.firstWhere( (item) => item.checklistsectionItem?.id == key, orElse: () => null, ); if (matchedItem != null) { // 匹配到已有答案,调用编辑接口 // 补充你的编辑API逻辑,传入matchedItem和answerValue } else { // 无匹配记录,调用新增接口 // 补充你的新增API逻辑,传入key和answerValue } }
方案2:优化查找效率,适合答案列表数据量大的场景
提前将答案列表转为ID为key的映射表,将查找复杂度从O(n)降到O(1),同时避免firstWhere的异常问题:
List<ChecklistAnswerItem> answerTable = await _repository.selectChecklistAnswerItemsList(); // 提前构造ID和答案对象的映射表 final Map<int, ChecklistAnswerItem> answerIdMap = { for (var item in answerTable) if (item.checklistsectionItem?.id != null) item.checklistsectionItem!.id: item }; for (var key in radioValue.keys) { final answerValue = radioValue[key]; if (answerValue == null || answerValue.toString().trim().isEmpty) continue; if (answerIdMap.containsKey(key)) { // 已有对应答案,调用编辑接口 final matchedItem = answerIdMap[key]!; // 编辑逻辑 } else { // 无对应答案,调用新增接口 // 新增逻辑 } }
内容的提问来源于stack exchange,提问作者Tony
相关产品推荐
相关产品推荐

