in my flutter project I'm using an api to fetch users and display it on the table. and to do that i used paginated data table. but when i try to use it in future builder the source for the table is not being passed to data source. source: dataSource(snapshot.data))
and it underlines on snapshot.data
and throws an error The argument type 'Object?' can't be assigned to the parameter type 'List<User>'
i referred to a question in stackoverflow this was the answer given . so why is this thrown?
the code is similar to the question i mentioned.
this is api...
import 'package:http/http.dart' as http;
import '../user_model.dart';
Future<List> fetchUsers() async {
Uri url = Uri.parse("https://jsonplaceholder.typicode.com/users");
final response = await http.get(url);
return usersFromJson(response.body);
}
this is the model...
import 'dart:convert';
List<User> usersFromJson(String str) =>
List<User>.from(json.decode(str).map((json) => User.fromJson(json)));
String usersToJson(List<User> data) =>
json.encode(List<dynamic>.from(data.map((e) => e.toJson())));
class User {
int? id;
String? name;
String? username;
String? email;
String? role;
String? password;
User(
{this.id,
this.name,
this.username,
this.email,
this.role,
this.password});
factory User.fromJson(Map<String, dynamic> json) => User(
email: json['title'],
name: json['title'],
id: json['id'],
username: json['title'],
role: json['title']);
Map<String, dynamic> toJson() => {
"name": name,
"username": username,
"email": email,
"role": role,
"password": password
};
}
this is the futurebuilder in the main.
FutureBuilder(
future: fetchUsers(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: [
PaginatedDataTable(
sortColumnIndex: sortColumnIndex,
sortAscending: isAscending,
columns: [
DataColumn(
label: const Text("Id"),
onSort: onSort),
DataColumn(
label: const Text("Name"),
onSort: onSort),
DataColumn(
label: const Text("Username"),
onSort: onSort),
DataColumn(
label: const Text("Email"),
onSort: onSort),
DataColumn(
label: const Text("Roles"),
onSort: onSort),
DataColumn(
label: const Text("Actions"),
onSort: onSort),
],
header: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Text(
"Manage Users",
style: TextStyle(
fontSize: width * 0.04,
fontWeight: FontWeight.normal),
),
MaterialButton(
onPressed: () {
showMaterialModalBottomSheet(
context: context,
builder: (context) => SizedBox(
height: height * 0.9,
child:
BottomSheetWidget(),
),
shape:
const RoundedRectangleBorder(
borderRadius:
BorderRadius.only(
topLeft: Radius
.circular(
15),
topRight: Radius
.circular(
15))));
},
color: const Color.fromRGBO(
30, 119, 66, 1),
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(10)),
child: Text(
"Add User",
style: TextStyle(
color: Colors.white,
fontSize: width * 0.03),
),
)
],
),
source: dataSource(snapshot.data))
],
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return const Center(child: CircularProgressIndicator());
})
i called the dataTable source as follows.
DataTableSource dataSource(List<User> userList) => MyTable(datasList: userList);
and finally dataTable source looks as follows
class MyTable extends DataTableSource {
MyTable({required this.datasList});
final List<User> datasList;
@override
DataRow? getRow(int index) {
return DataRow.byIndex(index: index, cells: [
DataCell(Text(datasList[index].id.toString())),
DataCell(Text(datasList[index].name.toString())),
DataCell(Text(datasList[index].username.toString())),
DataCell(Text(datasList[index].email.toString())),
DataCell(Text(datasList[index].role.toString())),
const DataCell(Text("Edit|Delete")),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => datasList.length;
@override
int get selectedRowCount => 0;
}
CodePudding user response:
Try to cast it as this:
source: dataSource(snapshot.data! as List<User>))
snapshot.data
is an object because it can be for example a List
, a Map
and so on. But you know that it is not null
and it is a List<User>
so you can just cast it.