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.
精彩评论