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

Flutter Web调试模式下Freezed自定义模型fromJson调用失败

问题描述

在Flutter Web项目中定义了如下Freezed自定义模型:

@freezed
class User with _$User {
  const factory User({
    required int id,
    required String name,
    required Address address,
    @Default(null) Contact? contact,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

Address、Coordinates及Contact模型定义如下:

@Freezed()
class Address with _$Address {
  const factory Address({
    required String type,
    required String address,
    required String subDistrict,
    required String district,
    required String state,
    required String country,
    required String pincode,
    Coordinates? coordinates,
  }) = _Address;

  factory Address.fromJson(Map<String, dynamic> json) => _$AddressFromJson(json);
}

@Freezed()
class Coordinates with _$Coordinates {
  const factory Coordinates({
    required double latitude,
    required double longitude,
  }) = _Coordinates;

  factory Coordinates.fromJson(Map<String, dynamic> json) => _$CoordinatesFromJson(json);
}
@Freezed()
class Contact with _$Contact {
  const factory Contact({
    @Default([]) List<String> email,
    @Default([]) List<String> mobile,
    @Default([]) List<String> landline,
    @Default([]) List<String> fax,
  }) = _Contact;

  factory Contact.fromJson(Map<String, dynamic> json) => _$ContactFromJson(json);
}

调用User.fromJson从JSON创建实例时,抛出错误:

NoSuchMethodError: tried to call a non-function, such as null: 'user$.User.fromJson'

问题细节:

  • 仅User模型出现该问题,移除@Default(null)后问题依旧
  • 已确认传入的是Map类型而非字符串
  • 仅调试模式触发,发布模式运行正常

环境及依赖版本:

Flutter 3.7.9 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 62bd79521d (2 weeks ago) • 2023-03-30 10:59:36 -0700
Engine • revision ec975089ac
Tools • Dart 2.19.6 • DevTools 2.20.1

dependencies:
  freezed_annotation: ^2.2.0
  json_annotation: ^4.8.0

dev_dependencies:
  build_runner: ^2.3.3
  freezed: ^2.3.2
  json_serializable: ^6.6.1

堆栈追踪:

C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 45:50   <fn>
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/zone.dart 1660:54                                 runUnary
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 147:18                           handleValue
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 767:44                           handleValueCallback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 796:13                           _propagateToListeners
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 567:5                            [_completeWithValue]
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/future_impl.dart 640:7                            callback
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 40:11                     _microtaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/async/schedule_microtask.dart 49:5                      _startMicrotaskLoop
C:/b/s/w/ir/cache/builder/src/out/host_debug/dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 166:15  <fn>

原因分析及解决方案

这个问题是Flutter Web调试模式下的代码生成延迟/未正确加载导致的。调试模式采用JIT编译,Freezed生成的_$UserFromJson方法没有被提前初始化加载,调用时就会出现null无法执行的错误;而发布模式是AOT编译,所有代码(包括生成代码)都会被提前打包,因此不会出现这个问题。

具体解决步骤:

  1. 强制预加载生成代码
    在调用User.fromJson之前,提前触发生成代码的加载,比如在初始化代码里添加:

    // 引用生成文件中的方法,触发加载
    import 'user.g.dart' as user_gen;
    
    void init() {
      // 仅触发加载,无需实际调用
      user_gen._$UserFromJson;
    }
    

    或者直接创建一个空的_$User实例:

    _$User(const User(id: 0, name: '', address: Address(type: '', address: '', subDistrict: '', district: '', state: '', country: '', pincode: '')));
    
  2. 彻底清理并重新生成代码
    执行以下命令,清除旧的生成文件并重新构建:

    flutter clean
    flutter pub get
    flutter pub run build_runner build --delete-conflicting-outputs
    
  3. 检查导入与代码结构
    确保所有模型的.g.dart生成文件都被正确导入,且没有循环导入的情况。

  4. 禁用Web延迟加载
    如果以上方法无效,可在pubspec.yaml中关闭Flutter Web的延迟加载:

    flutter:
      web:
        defer_js: false
    

内容的提问来源于stack exchange,提问作者Damien Leon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:03:31