Flutter接口获取地址异常:仅能获取shipto=0,无法获取后续地址
问题排查与解决方案
核心问题分析
触发RangeError (index): Invalid value: Only valid value is 0: 1的根本原因是数据模型未正确处理接口返回的多地址数组,导致后续尝试访问shipto=1及以上地址时,对应的列表仅包含一个元素(shipto=0的地址)。
具体修复步骤
1. 修正数据模型定义
确保Item和Address类正确映射接口结构,address字段必须为列表类型而非单个对象:
class Address { final int shipto; final String addr1; final String thanon; // 补充接口返回的其他字段 Address({ required this.shipto, required this.addr1, required this.thanon, // 对应其他字段的构造参数 }); factory Address.fromJson(Map<String, dynamic> json) { return Address( shipto: json['shipto'] ?? 0, addr1: json['addr1'] ?? '', thanon: json['thanon'] ?? '', // 解析其他字段 ); } } class Item { final String custnum; final String name; final List<Address> address; // 此处必须为List<Address>类型 Item({ required this.custnum, required this.name, required this.address, }); factory Item.fromJson(Map<String, dynamic> json) { // 将接口返回的address数组完整解析为List<Address> var addressList = json['address'] as List; List<Address> addresses = addressList.map((addr) => Address.fromJson(addr)).toList(); return Item( custnum: json['custnum'] ?? '', name: json['name'] ?? '', address: addresses, // 传入完整地址列表 ); } }
2. 优化fetchApi代码
现有请求逻辑基本可行,补充类型定义和异常处理避免潜在问题:
var loading = false; Future<List<Item>> fetchMos() async { // 明确返回类型 List<Item> listitem = []; loading = true; final client = http.Client(); try { const String mosUrl = '你的实际接口地址'; // 补充真实接口URL final url = Uri.parse(mosUrl); final headers = { 'Client-Token': '你的有效Token', // 补充真实Token 'Content-Type': 'application/json', }; final response = await client.get(url, headers: headers); if (response.statusCode == 200) { final data = jsonDecode(utf8.decode(response.bodyBytes))['items'] as List; listitem = data.map((itemJson) => Item.fromJson(itemJson)).toList(); } else { throw Exception('接口请求失败:${response.statusCode}'); } } catch (e) { print('请求异常:$e'); } finally { loading = false; client.close(); // 及时关闭客户端连接 } return listitem; }
3. 规范UI层访问逻辑
在UI中访问地址列表时,先判断长度再操作,避免越界:
// 示例:根据shipto值获取对应地址 Address? getAddressByShipto(Item item, int shipto) { try { return item.address.firstWhere((addr) => addr.shipto == shipto); } catch (e) { return null; // 无匹配时返回null } } // 示例:遍历所有地址 for (var addr in item.address) { print('shipto: ${addr.shipto}, 地址: ${addr.addr1}'); }
额外注意事项
- 你提供的接口JSON存在语法错误(缺少逗号分隔符),请确保实际接口返回的JSON格式合法。
- 必须补充
mosUrl和Client-Token的真实值,否则请求会失败。 - 网络请求中始终添加异常捕获,避免应用崩溃。
内容的提问来源于stack exchange,提问作者Ppnncs
相关产品推荐
相关产品推荐

