Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

flutter paginated data table with JSON api not working

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…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading