Home > Software design >  using set state in a data table source in flutter
using set state in a data table source in flutter

Time:09-20

I want to use setState() inside a DataTableSource class to when a button is pressed. so how can i accomplish that?

class MyTable extends DataTableSource {
  MyTable({required this.datasList, required this.context});
  final List<User> datasList;
  BuildContext context;
  final UserController userController = Get.put(UserController());

  Widget Button(String title, Color color, String id) {
    return MaterialButton(
      onPressed: () {
        deleteUser(id);
        
      },
      child: Text(
        title,
        style: const TextStyle(color: Colors.white),
      ),
      color: color,
      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
    );
  }

  @override
  DataRow? getRow(int index) {
    return DataRow.byIndex(index: index, cells: [
      DataCell(Text(datasList[index].id.toString())),
      DataCell(ConstrainedBox(
        constraints: const BoxConstraints(maxWidth: 100),
        child: Text(
          datasList[index].name.toString(),
          overflow: TextOverflow.ellipsis,
        ),
      )),
      DataCell(ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 100),
          child: Text(
            datasList[index].username.toString(),
            overflow: TextOverflow.ellipsis,
          ))),
      DataCell(ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 100),
          child: Text(
            datasList[index].email.toString(),
            overflow: TextOverflow.ellipsis,
          ))),
      DataCell(ConstrainedBox(
          constraints: const BoxConstraints(maxWidth: 100),
          child: Text(
            datasList[index].roles![0].name.toString(),
            overflow: TextOverflow.ellipsis,
          ))),
      DataCell(Row(
        children: [
          Button("Edit", Colors.lightBlue, datasList[index].id.toString()),
          const SizedBox(
            width: 5,
          ),
          Button("Delete", Colors.red, datasList[index].id.toString()),
        ],
      )),
    ]);
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => datasList.length;

  @override
  int get selectedRowCount => 0;
}

it is passed as below in my stateful class

DataTableSource dataSource(List<User> userList) =>
      MyTable(datasList: userList, context: context);

any solution?

the main page

StreamBuilder<List<User>>(
                        stream: fetchUsersFromModel().asStream(),
                        builder: (context, snapshot) {
                          if (snapshot.hasData) {
                            return 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! as List<User>));
                          } else if (snapshot.hasError) {
                            return Text("${snapshot.error}");
                          }
                          return const Center(
                              child: CircularProgressIndicator());
                        })

deleteUser call

Future deleteUser(var id) async {
  Uri url = Uri.parse("${BASE_URL}user/$id");
  final response = await http.delete(url, headers: <String, String>{
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer $TOKEN',
  }).then((value) => {
        //usersToJson(usersFromJson(value.body)),
        Get.snackbar("Deleted $id", "${value.body}",
            duration: const Duration(seconds: 30),
            colorText: Colors.black,
            backgroundColor: Colors.white),
      });}

CodePudding user response:

You use Getx. So, use Getx to controll this state...

in you UserController :

final _deleteUserPress = false.obs;
  get deleteUserPress => _deleteUserPress.value;
  set deleteUserPress(value) => _deleteUserPress.value = value;


setdeleteUserPress(bool value){
  deleteUserPress = value;
  update();
}

when deleteuser call :

onPressed: () {
  deleteUser(id);
  userController.setdeleteUserPress(true);
},

in yout Screen :

Obx(() => 
    userController.deleteUserPress
     ? // do someting
     : // do else
);

And if needed you set userController.deleteUserPress to false again

Edit ..

Or put the setDeleteUserPress In your deleteUser :

Future deleteUser(var id) async {
  final UserController userController = Get.put(UserController());

  Uri url = Uri.parse("${BASE_URL}user/$id");
  final response = await http.delete(url, headers: <String, String>{
    'Content-Type': 'application/json; charset=UTF-8',
    'Authorization': 'Bearer $TOKEN',
  });

  userController.setdeleteUserPress(true);

  Get.snackbar("Deleted $id", "${response.body}",
     duration: const Duration(seconds: 30),
        colorText: Colors.black,
        backgroundColor: Colors.white),
  });}
  • Related