You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter解析嵌套JSON时venue/branch详情为空问题求助

Flutter API解析venue/branch详情为null的排查与解决方案

问题描述

Flutter应用调用API获取订单数据时,venue_detail、branch_detail及其嵌套字段返回null,但Postman中能看到完整的非空响应,API本身正常,问题出在数据解析环节。

排查步骤

  1. 核对请求一致性

    • 对比Flutter代码与Postman的请求参数:确认BASE_URL、Authorization令牌、user_id参数完全一致
    • 检查请求头:确保Content-type、Accept头与Postman配置相同
  2. 查看原始解析数据

    • 运行代码后查看控制台的getting pending orders $extractedData输出,确认返回的数组中每个订单对象是否包含venue_detail和branch_detail字段
    • 在extractedData.forEach循环内添加print('单个订单数据: $prodData');,直接打印单条订单的完整结构,定位字段是否存在
  3. 检查类型转换与空安全

    • 当前代码中json.decode(response.body)['success'] as List<dynamic>属于强制类型转换,若API返回结构异常会导致解析失败,需添加类型校验

修复方案

1. 优化请求与解析的类型安全

修改解析逻辑,增加类型检查与空安全处理:

Future<bool> getPresentOrders({
  required token,
  required userId,
}) async {
  try {
    final response = await http.post(
      Uri.parse(BASE_URL + '/api/get_present_orders'),
      headers: {
        "Content-type": "application/json",
        "Accept": "application/json",
        'Authorization': 'Bearer $token',
      },
      body: jsonEncode({
        'user_id': userId,
      }),
    );

    final responseData = json.decode(response.body);
    // 先校验顶层结构
    if (responseData is! Map<String, dynamic> || !responseData.containsKey('success')) {
      return false;
    }

    final extractedData = responseData['success'];
    // 校验success字段是否为列表
    if (extractedData is! List) {
      return false;
    }

    print('获取的订单列表数据: $extractedData');

    if (response.statusCode == 200) {
      final List<Order> loadedOrderList = [];

      for (final prodData in extractedData) {
        // 确保prodData是Map类型
        if (prodData is! Map<String, dynamic>) continue;
        
        // 提取嵌套对象并做空安全处理
        final venueDetail = prodData['venue_detail'] as Map<String, dynamic>?;
        final branchDetail = prodData['branch_detail'] as Map<String, dynamic>?;

        loadedOrderList.add(
          Order(
            venueId: prodData['venue_id'].toString(),
            branchId: prodData['branch_id'].toString(),
            orderNumber: prodData['order_unique_id'],
            orderTime: prodData['order_time'],
            total: double.parse(prodData['total_price'] ?? '0.00'),
            orderType: prodData['order_type'],
            currentStatus: prodData['current_status'],
            venueName: venueDetail?['venue_name'] ?? '未知商家',
            venueType: venueDetail?['venue_type'] ?? '未知类型',
            branchName: branchDetail?['name'] ?? '未知门店',
            venueLogo: venueDetail?['logo_url'] ?? '',
            orderItems: () {
              try {
                final itemsJson = json.decode(prodData['items_detail'] ?? '[]') as List;
                return itemsJson.map((item) {
                  final itemMap = item as Map<String, dynamic>;
                  return CartItem(
                    id: itemMap['id'].toString(),
                    title: itemMap['title'].toString(),
                    quantity: int.parse(itemMap['quantity'].toString()),
                    price: double.parse(itemMap['price'].toString()),
                    specialInstruction: itemMap['instructions'].toString(),
                  );
                }).toList();
              } catch (e) {
                print('解析订单商品失败: $e');
                return [];
              }
            }(),
          ),
        );
      }

      _or = loadedOrderList.reversed.toList();
    } else {
      print('请求失败: ${response.statusCode}');
    }

    notifyListeners();
    return true;
  } catch (error) {
    print('解析异常: $error');
    rethrow;
  }
}

2. 关键优化点

  • 增加类型校验:确保每个层级的JSON结构符合预期,避免强制类型转换导致的隐性错误
  • 使用空安全操作符?.:访问嵌套字段时自动处理null情况,避免直接访问null对象的属性
  • 添加异常捕获:对商品列表解析单独捕获异常,避免单个订单解析失败导致整个列表加载失败
  • 处理字符串转数值:total_price是字符串类型,需显式转为double,同时添加默认值

3. 额外排查点

  • 若控制台打印的extractedData中确实没有venue_detail和branch_detail,说明Flutter发送的请求与Postman不一致,需再次核对请求头、令牌、参数
  • 检查API是否存在权限差异:部分API可能根据令牌返回不同字段,确保Flutter使用的令牌与Postman相同

内容的提问来源于stack exchange,提问作者Zulqarnain Haider

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 16:48:10