flutter 无法访问冻结的自定义模型的fromJson函数

wfveoks0  于 2023-04-22  发布在  Flutter
关注(0)|答案(1)|浏览(149)

我在flutter web项目中声明了一个自定义冻结模型,如下所示:

@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);
}

AddressContact的模型如下:

@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);
}

现在,问题是,当我尝试从json创建这个模型的示例时,它会抛出以下错误:

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

然而,这并不是发生在项目中的所有模型上,我面对这个问题只是针对前面提到的一个。
我试着不设置@Default(null),但同样的问题出现了。我已经确保传递的数据是json而不是String。
这是什么问题

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>
0h4hbjxa

0h4hbjxa1#

添加部件语句yourfile.g.dart
确保您已成功运行build_runner
尝试使用--delete-conflicting-outputs运行
如果需要序列化/反序列化嵌套的冻结类,还必须在build.yaml中添加@JsonSerializable(explicitToJson: true)或设置explicit_to_json
@Default(null)可以/应该被删除。它没有增加任何东西。

编辑

我刚刚复制了你的模型,成功地生成了所有的文件,创建了模型,序列化和反序列化了它。在发布模式和调试模式下工作正常。
我删除了@Default(null)的联系。
模型:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'temp.freezed.dart';
part 'temp.g.dart';

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

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

@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);
}

使用这里的模型:

import 'dart:convert';

import 'dart:io';
import 'package:console_app/temp.dart';

void main(List<String> arguments) {
  var user = User(
    id: 42,
    name: 'name',
    contact: Contact(
      email: ['test@email.com'],
      fax: ['0123-456789'],
      landline: ['0246-8101214'],
      mobile: ['0135-791113'],
    ),
    address: Address(
        type: 'type',
        address: 'address',
        subDistrict: 'subDistrict',
        district: 'district',
        state: 'state',
        country: 'country',
        pincode: 'pincode',
        coordinates: Coordinates(
          latitude: 12.34567,
          longitude: 98.7654,
        )),
  );
  var jsonData = jsonEncode(user.toJson());
  var file = File('user.json');
  file.writeAsStringSync(jsonData);
  var readUserFromFile = User.fromJson(jsonDecode(file.readAsStringSync()));
  assert(user == readUserFromFile);
  print(readUserFromFile);
}

这是生成的json文件:

{
  "id": 42,
  "name": "name",
  "address": {
    "type": "type",
    "address": "address",
    "subDistrict": "subDistrict",
    "district": "district",
    "state": "state",
    "country": "country",
    "pincode": "pincode",
    "coordinates": { "latitude": 12.34567, "longitude": 98.7654 }
  },
  "contact": {
    "email": ["test@email.com"],
    "mobile": ["0135-791113"],
    "landline": ["0246-8101214"],
    "fax": ["0123-456789"]
  }
}

这是打印出来的结果:

User(id: 42, name: name, address: Address(type: type, address: address, subDistrict: subDistrict, district: district, state: state, country: country, pincode: pincode, coordinates: Coordinates(latitude: 12.34567, longitude: 98.7654)), contact: Contact(email: [test@email.com], mobile: [0135-791113], landline: [0246-8101214], fax: [0123-456789]))

相关问题