开发者

type 'List<dynamic>' is not a subtype of type 'List<DataRow>'

开发者 https://www.devze.com 2022-12-07 18:46 出处:网络
i\'m fetching data from API and want to show that on a table. api response is something like : { "url": [

i'm fetching data from API and want to show that on a table.

api response is something like :

{
"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": .....
        }
    ]
}
}

i want to show elements in the lots . i used futurebuilder to show data but this error happend.

════════ 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 code added below:

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("-")),
                          ],
                        )
                      ],
              ),
            );
          },
        )

is this happend for type is not matching correctly? how do i solve this?

another suggestion needed , do i need to call data in initState and save the response to a List? will it be a good way? then how can i achieve that? ShipmentLotViewModel class below:

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,
};

}


A better approach will be to try the following and get required data.

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

and in your FutureBuilder's future, call api like following:

future: ApiService(),

now use snapshot.data to access your required data.

P.S. Please don't forget to

import 'dart:convert';

For your second question, you don't need to call your data api in initState as it'll get data on the go.

0

精彩评论

暂无评论...
验证码 换一张
取 消