我已经冻结模型(简化):
part 'initial_data_model.freezed.dart';
part 'initial_data_model.g.dart';
@freezed
class InitialDataModel with _$InitialDataModel {
const factory InitialDataModel() = Data;
const factory InitialDataModel.loading() = Loading;
const factory InitialDataModel.error([String? message]) = Error;
factory InitialDataModel.fromJson(Map<String, dynamic> json) => _$InitialDataModelFromJson(json);
}
文档说明了如何在字段上而不是在模型本身上分配自定义转换器
我从后端得到json,在api_provider的某个地方我做return InitialDataModel.fromJson(json);
我无法控制json结构,没有"runtimeType"和其他愚蠢的多余的东西
当我想从json中创建模型时,我调用fromJson
我有这个
flutter: CheckedFromJsonException
Could not create `InitialDataModel`.
There is a problem with "runtimeType".
Invalid union type "null"!
好的,还是
我有api_provider
final apiProvider = Provider<_ApiProvider>((ref) => _ApiProvider(ref.read));
class _ApiProvider {
final Reader read;
_ApiProvider(this.read);
Future<InitialDataModel> fetchInitialData() async {
final result = await read(repositoryProvider).send('/initial_data');
return result.when(
(json) => InitialDataModel.fromJson(json),
error: (e) => InitialDataModel.error(e),
);
}
}
你可能会看到我试图从json创建InitialDataModel
这行抛出我上面提到的错误
我不明白如何从json中创建InitialDataModel,现在在我的例子中它只是一个空模型,没有字段
(json) => InitialDataModel.fromJson(json),
json
这里是地图,它显示一个错误,即使我传递简单的空地图{}
而不是真正的json对象
最简单的解决方案是使用正确的构造函数而不是_$InitialDataModelFromJson。例子:
@freezed
class InitialDataModel with _$InitialDataModel {
const factory InitialDataModel() = Data;
...
factory InitialDataModel.fromJson(Map<String, dynamic> json) => Data.fromJson(json);
}
缺点当然是,你只能使用fromJson当你确定你有正确的json,这不是很好。实际上我不推荐这种方法,因为它把检查有效性和调用正确构造函数的负担留给了调用者。
另一个解决方案,可能是最好的,是遵循文档并创建一个自定义转换器,尽管这将要求您有两个分离的类。
否则,您可以选择一种不同的方法,将数据类从联合中分离出来,这样您将拥有一个仅用于请求状态的联合和一个用于成功响应的数据类:
@freezed
class InitialDataModel with _$InitialDataModel {
factory InitialDataModel(/* here go your attributes */) = Data;
factory InitialDataModel.fromJson(Map<String, dynamic> json) => _$InitialDataModelFromJson(json);
}
@freezed
class Status with _$Status {
const factory Status.success(InitialDataModel model) = Data;
const factory Status.loading() = Loading;
const factory Status.error([String? message]) = Error;
}
和
[...]
return result.when(
(json) => Status.success(InitialDataModel.fromJson(json)),
error: (e) => Status.error(e),
);
[...]