我已经看了很多例子,但我仍然在努力解码下面的json.我是一个新手,我发现json.decode
只在我映射为List<dynamic>
时才有效.但我相信我最终需要把它映射到List<Map<String, Map<String, dynamic>>
.我可能是错的,所以我在寻找输入.我创建了两个模型,ProductLine
和PartNumber
.挑战在于,显示为Product line #
的键需要作为值添加到PartNumber
对象以及ProductLine
的name
值.这些键可以是任何字符串值,并且不是预先确定的.
[
{
"Product line 1": [
{
"partNumber": "160-9013-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9104-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9105-900",
"orderable": false,
"description": "Part Number Description"
}
]
},
{
"Product line 2": [
{
"partNumber": "160-9113-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9114-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9115-900",
"orderable": false,
"description": "Part Number Description"
}
]
},
{
"Product line 3": [
{
"partNumber": "160-9205-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9211-900",
"orderable": true,
"description": "Part Number Description"
},
{
"partNumber": "160-9212-900",
"orderable": false,
"description": "Part Number Description"
}
]
}
]
这是我的ProductLine
号和PartNumber
号的型号.@JsonSerializable()
代码是由Build_Runner自动生成的.
const uuid = Uuid();
@JsonSerializable()
class PartNumber {
PartNumber({
String? id,
required this.partNumber,
required this.orderable,
required this.description,
required this.productLine,
}) : id = id ?? uuid.v4();
final String id;
final String partNumber;
final bool orderable;
final String description;
final String productLine;
factory PartNumber.fromJson(Map<String, dynamic> json) =>
_$PartNumberFromJson(json);
Map<String, dynamic> toJson() => _$PartNumberToJson(this);
PartNumber _$PartNumberFromJson(Map<String, dynamic> json) => PartNumber(
id: json['id'] as String?,
partNumber: json['partNumber'] as String,
orderable: json['orderable'] as bool,
description: json['description'] as String,
productLine: json['productLine'] as String,
);
Map<String, dynamic> _$PartNumberToJson(PartNumber instance) =>
<String, dynamic>{
'id': instance.id,
'partNumber': instance.partNumber,
'orderable': instance.orderable,
'description': instance.description,
'productLine': instance.productLine,
};
}
@JsonSerializable()
class ProductLine {
ProductLine({
String? id,
required this.name,
required this.partNumbers,
}) : id = id ?? uuid.v4();
final String id;
final String name;
final List<PartNumber> partNumbers;
factory ProductLine.fromJson(Map<String, dynamic> json) =>
_$ProductLineFromJson(json);
Map<String, dynamic> toJson() => _$ProductLineToJson(this);
ProductLine _$ProductLineFromJson(Map<String, dynamic> json) => ProductLine(
id: json['id'] as String?,
name: json['name'] as String,
partNumbers: (json['partNumbers'] as List<dynamic>)
.map((e) => PartNumber.fromJson(e as Map<String, dynamic>))
.toList(),
);
Map<String, dynamic> _$ProductLineToJson(ProductLine instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'partNumbers': instance.partNumbers,
};
}
我得到的错误是:
E/flutter (18120): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast E/flutter (18120): #0 _$ProductLineFromJson (package:test_app/models/product_line.g.dart:11:26) E/flutter (18120): #1 new ProductLine.fromJson (package:test_app/models/product_line.dart:24:7) E/flutter (18120): #2 PartNumberManager.formatPartNumbers (package:test_app/managers/part_number_manager.dart:62:39) E/flutter (18120): E/flutter (18120): #3 PartNumberManager.loadPartNumbers (package:test_app/managers/part_number_manager.dart:36:5) E/flutter (18120):
以下是读取json并构建模型的代码.我做错了什么?
class PartNumberManager {
List<PartNumber>? partNumbers;
Future<bool> loadPartNumbers() async {
await formatPartNumbers();
final partNumbersLoaded = await batchInsertPartNumbers();
return partNumbersLoaded;
}
// Read part_numbers.json file before adding data to the sql database
Future<List<dynamic>> readJson() async {
try {
final String response =
await rootBundle.loadString('assets/part_numbers.json');
final data = (json.decode(response) as List<dynamic>);
return data;
} catch (error) {
throw Exception(
'PartNumberManager, Unexpected error reading JSON: $error');
}
}
Future<void> formatPartNumbers() async {
List<ProductLine> tmpProductLines = [];
List<dynamic> data = await readJson();
for (var i = 0; i < data.length; i++) {
final productLine = ProductLine.fromJson(data[i]);
tmpProductLines.add(productLine);
}
for (var product in tmpProductLines) {
for (var pnum in product.partNumbers) {
final partNumber = PartNumber(
partNumber: pnum.partNumber,
orderable: pnum.orderable,
description: pnum.description,
productLine: product.name,
);
partNumbers!.add(partNumber);
}
}
}
}