Home > Blockchain >  flutter paginated data table with JSON api not working
flutter paginated data table with JSON api not working

Time:09-14

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.

  • Related