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

Flutter报错:'Null'不是'String'子类型,求API数据解析方案

Flutter 3.0.0 API数据解析报错:type 'Null' is not a subtype of type 'String' 求助

我在使用Flutter SDK 3.0.0从API获取数据时,长期遇到**"type 'Null' is not a subtype of type 'String'"**未处理异常,尝试多种网络方案仍未解决。以下是相关代码及报错信息,恳请帮忙解决:

模型类代码

class Product {
  int? _totalSize;
  int? _typeId;
  int? _offset;
  late List<ProductModel> _products;
  List<ProductModel> get products => _products;

  Product({required totalSize, required typeId,  required offset, required products}){
    this._totalSize = totalSize;
    this._typeId = typeId;
    this._offset = offset;
    this._products = products;
  }

  factory Product.fromJson(Map<String, dynamic> json) {

    var list = json['products'] as List;
    List<ProductModel> productsList = list.map((e) => ProductModel.fromJson(e as Map<String, dynamic>)).toList();

    return Product(
        totalSize : json['total_size'] as int,
        typeId : json['type_id'] as int,
        offset : json['offset'] as int,
        products: productsList
    );
  }
}

class ProductModel {
  int? id;
  String? name;
  String? description;
  int? price;
  int? stars;
  String? img;
  String? location;
  String? createdAt;
  String? updatedAt;
  int? typeId;

  ProductModel(
      {required this.id,
        required this.name,
        required this.description,
        required this.price,
        required this.stars,
        required this.img,
        required this.location,
        required this.createdAt,
        required this.updatedAt,
        required this.typeId});

  factory ProductModel.fromJson(Map<String, dynamic> json) {
    return ProductModel(
        id: json['id'] as int,
        name: json['name'] as String,
        description: json['description'] as String,
        price: json['price'] as int,
        stars: json['stars'] as int,
        img: json['img'] as String,
        location: json['location'] as String,
        createdAt: json['createdAt'] as String,
        updatedAt: json['updatedAt'] as String,
        typeId: json['typeId'] as int
    );
  }
}

控制器类代码

import 'dart:convert';

import 'package:get/get.dart';
import 'package:licores_app/data/repository/category_product_repo.dart';

import '../models/products_model.dart';

class CategoryProductController extends GetxController {
  final CategoryProductRepo categoryProductRepo;
  CategoryProductController({required this.categoryProductRepo});

  List<dynamic> _categoryProductList = [];

  // Get Method from Product Model
  List<dynamic> get CategoryProductList => _categoryProductList;

  // Response from repo product method
  Future<void> getCategoryProductList() async {
    Response response =  await categoryProductRepo.getCategoryProductList();

    print('got the products'); // This is right to this point

    if (response.statusCode == 200) {
      // Init to null not to repeat
      _categoryProductList = [];
      _categoryProductList.addAll(Product
          .fromJson(jsonDecode(response.body))
          .products); // --> Here the
      // Unhandled Exception: type 'Null' is not a subtype of type 'String'
      print(_categoryProductList);
      update();
    } else { // I added the curly braces but took off because I was 
       // debugging the problem still persist!
       print('not able to get product list json');
    }
  }
}

报错信息

[ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: type 'Null' is not a subtype of type 'String'
E/flutter ( 6243): #0      CategoryProductController.getCategoryProductList (package:licores_app/controllers/category_product_controller.dart:27:72)
E/flutter ( 6243): <asynchronous suspension>

问题原因

API返回的JSON中,某个本该是String/int类型的字段实际为null,但你在fromJson方法里用as String/as int强制转换null,Dart不允许将null强转为非空的String/int类型,即使成员变量是可空类型,强转操作依然会报错。同时构造函数的required修饰与可空成员变量存在矛盾,进一步加剧问题。

解决步骤

1. 修正类型转换,允许空值

修改ProductModel.fromJson,将每个字段的强转改为可空类型转换(比如as String?而非as String),这样当字段为null时不会触发类型转换异常:

factory ProductModel.fromJson(Map<String, dynamic> json) {
  return ProductModel(
      id: json['id'] as int?,
      name: json['name'] as String?,
      description: json['description'] as String?,
      price: json['price'] as int?,
      stars: json['stars'] as int?,
      img: json['img'] as String?,
      location: json['location'] as String?,
      createdAt: json['createdAt'] as String?,
      updatedAt: json['updatedAt'] as String?,
      typeId: json['typeId'] as int?
  );
}

2. 调整构造函数的required修饰

因为成员变量都是可空类型,构造函数不需要强制required,去掉后允许传入null:

ProductModel({
  this.id,
  this.name,
  this.description,
  this.price,
  this.stars,
  this.img,
  this.location,
  this.createdAt,
  this.updatedAt,
  this.typeId
});

3. 处理外层Product类的空值

同样修正Product.fromJson的字段转换,避免外层字段为null时报错:

return Product(
    totalSize : json['total_size'] as int?,
    typeId : json['type_id'] as int?,
    offset : json['offset'] as int?,
    products: productsList
);

同时修改Product的构造函数,去掉非必要的required:

Product({totalSize, typeId, offset, required products}){
  this._totalSize = totalSize;
  this._typeId = typeId;
  this._offset = offset;
  this._products = products;
}

4. 定位具体空值字段(可选)

如果想精准排查哪个字段为null,可以在控制器中打印API返回的原始数据:

Future<void> getCategoryProductList() async {
  Response response =  await categoryProductRepo.getCategoryProductList();
  print('API原始返回: ${response.body}'); // 新增此行
  // ... 其余代码不变
}

根据打印结果,可给特定空字段设置默认值,比如:

img: json['img'] as String? ?? 'https://your-default-image-url.com',

内容的提问来源于stack exchange,提问作者Lance Deal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 13:48:22