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

Flutter报错:String无法转为Map<String,dynamic> 求问题排查

Flutter购物车解析错误:type String is not a subtype of type Map<String, dynamic> 解决方案

问题描述

在实现添加商品到购物车功能时,触发类型转换错误:type String is not a subtype of type Map<String, dynamic>。调试确认接口返回的response.data是_Map<String, dynamic>,且已正确提取updatedCart字段,但调用Cart.fromJson解析时仍报错。

核心原因

错误并非来自Cart或CartItem的直接解析,而是Product模型的fromJson方法中,存在字符串类型字段被当作数值类型解析的情况。从后端返回的JSON可见:

  • productPrice是带逗号的字符串(如"24,360"),若Product模型定义为int/double且未做转换,会导致类型不匹配
  • productDaysOfDelivery是字符串(如"3"),若模型定义为int但未用int.parse转换,会触发错误
  • productQuantity是空字符串,若模型定义为int且未处理空值,同样会引发异常

解决方案

1. 修正Product模型的fromJson方法

确保每个字段类型与后端返回严格匹配,对字符串类型的数值字段做转换处理:

class Product {
  final String id;
  final String productName;
  final String productBrandName;
  final double productPrice;
  final String productDescription;
  final int productDaysOfDelivery;
  final String productType;
  final String productSize;
  final String? productQuantity;
  final List<ProductImage> productImages;
  final bool productAvailability;
  final String productStatus;
  final DateTime createdAt;
  final DateTime updatedAt;

  Product({
    required this.id,
    required this.productName,
    required this.productBrandName,
    required this.productPrice,
    required this.productDescription,
    required this.productDaysOfDelivery,
    required this.productType,
    required this.productSize,
    this.productQuantity,
    required this.productImages,
    required this.productAvailability,
    required this.productStatus,
    required this.createdAt,
    required this.updatedAt,
  });

  factory Product.fromJson(Map<String, dynamic> json) {
    // 处理带逗号的价格字符串,转为double
    final priceStr = json['productPrice'].toString().replaceAll(',', '');
    final price = double.tryParse(priceStr) ?? 0.0;

    // 交货天数字符串转int,空值默认0
    final deliveryDays = int.tryParse(json['productDaysOfDelivery'].toString()) ?? 0;

    return Product(
      id: json['_id'] as String,
      productName: json['productName'] as String,
      productBrandName: json['productBrandName'] as String,
      productPrice: price,
      productDescription: json['productDescription'] as String,
      productDaysOfDelivery: deliveryDays,
      productType: json['productType'] as String,
      productSize: json['productSize'] as String,
      productQuantity: json['productQuantity'] as String?,
      productImages: (json['productImages'] as List)
          .map((img) => ProductImage.fromJson(img as Map<String, dynamic>))
          .toList(),
      productAvailability: json['productAvailability'] as bool,
      productStatus: json['productStatus'] as String,
      createdAt: DateTime.parse(json['createdAt'] as String),
      updatedAt: DateTime.parse(json['updatedAt'] as String),
    );
  }
}

// 补充ProductImage子模型
class ProductImage {
  final String productUrl;
  final String id;

  ProductImage({
    required this.productUrl,
    required this.id,
  });

  factory ProductImage.fromJson(Map<String, dynamic> json) {
    return ProductImage(
      productUrl: json['productUrl'] as String,
      id: json['_id'] as String,
    );
  }
}

2. 为Cart和CartItem的解析增加安全校验

避免强制转换崩溃,使用as?结合空值兜底:

// 修正CartItem.fromJson
factory CartItem.fromJson(Map<String, dynamic> json) {
  final productJson = json['product'] as Map<String, dynamic>?;
  if (productJson == null) {
    throw Exception('购物项中缺少商品数据');
  }

  return CartItem(
    product: Product.fromJson(productJson),
    quantity: json['quantity'] as int? ?? 1, // 空值默认1件
    id: json['_id'] as String? ?? '', // 空值默认空字符串
  );
}

// 修正Cart.fromJson
factory Cart.fromJson(Map<String, dynamic> json) {
  return Cart(
    id: json['_id'] as String? ?? '',
    userId: json['user'] as String? ?? '',
    items: (json['items'] as List? ?? [])
        .map((item) {
          if (item is Map<String, dynamic>) {
            return CartItem.fromJson(item);
          }
          throw Exception('购物项格式无效');
        })
        .toList(),
  );
}

3. 接口请求代码增强容错

提取updatedCart时增加空值判断:

Future<Cart?> addProductToCart(String productId, int quantity) async {
  try {
    const endpoint = "user/add_product_cart";
    final response = await apiProvider.post(endpoint, data: {
      'productId': productId,
      'quantity': quantity,
    });

    if (response.data is Map<String, dynamic>) {
      final updatedCartData = response.data['updatedCart'] as Map<String, dynamic>?;
      if (updatedCartData == null) {
        throw Exception('缺少更新后的购物车数据');
      }
      return Cart.fromJson(updatedCartData);
    } else {
      throw Exception('响应格式不符合预期');
    }
  } catch (e) {
    print("Error: $e");
    rethrow;
  }
}

验证步骤

  1. 重新运行项目,执行添加商品到购物车操作
  2. 查看控制台日志,确认是否还有类型转换错误
  3. 检查Cart对象是否成功解析并包含正确的商品数据

内容的提问来源于stack exchange,提问作者Hemmyhtec Creatives

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 23:07:02