dart 类型“List< dynamic>”不是类型“List”的子类型< DataRow>

nhaq1z21  于 2022-12-16  发布在  其他
关注(0)|答案(1)|浏览(143)

我正在从API获取数据,并希望在表中显示。
API响应类似于:

{
"url": [
    ....
],
"date-time": ,
"method": "GET",
"data": {
    "id": 86,
    "to_country": "Malaysia",
    "start_date": "2022-11-22",
    "end_date": "2022-12-02",
    "freight_category": "AIR_FREIGHT",
    "shipment_number": ...
    "location_status": "Under Processing Warehouse, Malaysia",
    "lots": [
        {
            "id": 843,
            "booking": ....
            "location_status": "Under Processing Warehouse, Malaysia",
            "branch": "Kuala Lumpur Office",
            "reference": .....
        }
    ]
}
}

我想显示的元素在地段.我用futurebuilder来显示数据,但这个错误发生.

════════ Exception caught by widgets library ═══════════════════════════════════
type 'List<dynamic>' is not a subtype of type 'List<DataRow>'
The relevant error-causing widget was
FutureBuilder<ShipmentLotViewModel?>

Futurebuilder代码添加如下:

FutureBuilder<ShipmentLotViewModel?>(
          future: ApiService().getLotViewData(widget.id),
          builder: (context, AsyncSnapshot snapshot) {
            return SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: DataTable(
                sortAscending: true,
                sortColumnIndex: 0,
                showBottomBorder: true,
                decoration: BoxDecoration(
                  border: Border.all(color: Colors.grey.shade300),
                ),
                columns: [
                  DataColumn(
                    label: Text("Reference"),
                  ),
                  DataColumn(
                    label: Text("Location Status"),
                  ),
                  DataColumn(
                    label: Text("Lots of"),
                  ),
                ],
                rows: snapshot.hasData
                    ? snapshot.data.data.lots
                        .map(
                          (e) => DataRow(
                            cells: [
                              DataCell(Text("${e.reference}")),
                              DataCell(Text("${e.id}")),
                              DataCell(Text("${e.booking}")),
                            ],
                          ),
                        )
                        .toList()
                    : [
                        DataRow(
                          cells: [
                            DataCell(Text("-")),
                            DataCell(Text("-")),
                            DataCell(Text("-")),
                          ],
                        )
                      ],
              ),
            );
          },
        )

这是不是因为类型不匹配而发生的?我该如何解决这个问题?
需要另一个建议,我是否需要调用initState中的数据并将响应保存到列表中?这是一个好方法吗?那么我如何实现这一点?ShipmentLotViewModel类如下:

class ShipmentLotViewModel {
ShipmentLotViewModel({
    this.url,
    this.dateTime,
    this.method,
    this.data,
});

List<String>? url;
DateTime? dateTime;
String ?method;
Data ?data;

factory ShipmentLotViewModel.fromJson(Map<String, dynamic> json) 
=> ShipmentLotViewModel(
    url: List<String>.from(json["url"].map((x) => x)),
    dateTime: DateTime.parse(json["date-time"]),
    method: json["method"],
    data: Data.fromJson(json["data"]),
);

Map<String, dynamic> toJson() => {
    "url": List<dynamic>.from(url!.map((x) => x)),
    "date-time": dateTime!.toIso8601String(),
    "method": method,
    "data": data!.toJson(),
};
}

class Data {
Data({
    this.id,
    this.toCountry,
    this.startDate,
    this.endDate,
    this.freightCategory,
    this.shipmentNumber,
    this.locationStatus,
    this.lots,
});

int ?id;
String ?toCountry;
DateTime? startDate;
DateTime? endDate;
String? freightCategory;
String? shipmentNumber;
String ?locationStatus;
List<Lot> ?lots;

factory Data.fromJson(Map<String, dynamic> json) => Data(
    id: json["id"],
    toCountry: json["to_country"],
    startDate: DateTime.parse(json["start_date"]),
    endDate: DateTime.parse(json["end_date"]),
    freightCategory: json["freight_category"],
    shipmentNumber: json["shipment_number"],
    locationStatus: json["location_status"],
    lots: List<Lot>.from(json["lots"].map((x) => 
    Lot.fromJson(x))),
    );

   Map<String, dynamic> toJson() => {
    "id": id,
    "to_country": toCountry,
    "start_date": "${startDate!.year.toString().padLeft(4, 
 '0')}-${startDate!.month.toString().padLeft(2, 
'0')}-${startDate!.day.toString().padLeft(2, '0')}",
    "end_date": "${endDate!.year.toString().padLeft(4, 
 '0')}-${endDate!.month.toString().padLeft(2, 
'0')}-${endDate!.day.toString().padLeft(2, '0')}",
    "freight_category": freightCategory,
    "shipment_number": shipmentNumber,
    "location_status": locationStatus,
    "lots": List<dynamic>.from(lots!.map((x) => x.toJson())),
};
}

class Lot {
Lot({
    this.id,
    this.booking,
    this.locationStatus,
    this.branch,
    this.reference,
});

int ? id;
String? booking;
String? locationStatus;
String? branch;
String? reference;

factory Lot.fromJson(Map<String, dynamic> json) => Lot(
    id: json["id"],
    booking: json["booking"],
    locationStatus: json["location_status"],
    branch: json["branch"],
    reference: json["reference"],
);

Map<String, dynamic> toJson() => {
    "id": id,
    "booking": booking,
    "location_status": locationStatus,
    "branch": branch,
    "reference": reference,
};

}

wmvff8tz

wmvff8tz1#

更好的方法是尝试以下方法并获取所需的数据。

Future<ShipmentLotViewModel>ApiService() async {
   var uri = "your_uri";
   http.Response response = await http.get(Uri.parse(uri));
   var data = jsonDecode(response.body.toString());
   if (response.statusCode == 200) {
     return ShipmentLotViewModel.fromJson(data);
    }
   else {
     return ShipmentLotViewModel.fromJson(data);
    }
    }
   }

在你的FutureBuilder的未来,像下面这样调用API:

future: ApiService(),

现在使用snapshot.data来访问所需的数据。
另外,请不要忘记
导入“dart:转换”;
对于您的第二个问题,您不需要在initState中调用数据API,因为它会在运行中获取数据。

相关问题