checkbox list does not update in flutter getx

1,472

Updated Answer:

If you tried wrapping an an Obx and it didn't work, use GetBuilder<SearchController> instead.

GetBuilder<SearchController>(
    builder: (_) =>  controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
            : SingleChildScrollView(...))

When you call update() it will trigger a rebuild no matter what, with the updated values. The only reason I can think of why Obx didn't work is that perhaps when it comes to lists in only responds to an addition or removal of an item in the list and not a change in a property nested inside.

In general, you'll probably find that in most cases using an observable stream based variable is not really needed. GetBuilder can handle most or all of what you need done unless you're doing something stream based (binding to an external Firebase collection for example). Nothing wrong with either, but GetBuilder is the most performant option as streams by their nature are a bit more expensive.

Original answer:

I suggest you read the docs regarding proper usage before claiming there's a bug in someone else's code. That goes for any package that you're using.

It's stated all over the Readme and in the basic counter app example that observable variables need to be placed in an Obx widget, otherwise there's nothing triggering a rebuild based on the updated state of an observable GetX variable.

The child of your Container should be

Obx(() => controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
            : SingleChildScrollView(...))
Share:
1,472
Speeder
Author by

Speeder

I am struggling hard to do my work at 100% quality. React, React Native and Flutter are my best skill sets.

Updated on January 01, 2023

Comments

  • Speeder
    Speeder 10 months

    I am using GetX for the state management in flutter project. My problem is when I click on the checkbox it updates the state in controller but does not show the result in UI. In general the changed state should change the UI too. I am not sure what is the problem but I think there is a bug in using the observable variable in getx. How to solve this problem? If the post is not clear then please ask me.

    This is the view.

    class FilterBottomSheetWidget extends GetView<SearchController> {
    @override
    Widget build(BuildContext context) {
      return Container(
      height: Get.height - 90,
      child: Stack(
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.only(top: 80),
            child: Container(
              padding: EdgeInsets.only(top: 20, bottom: 15, left: 4, right: 4),
              child: controller.expiringContractStatus.isEmpty ? CircularLoadingWidget(height: 100)
                : SingleChildScrollView(
                  scrollDirection: Axis.vertical,
                  child: ExpansionTile(
                          title: Text("Contract Status".tr, style: Get.textTheme.bodyText2),
                          children: List.generate(controller.expiringContractStatus.length, (index) {
                            var _expiringContractStatus = controller.expiringContractStatus.elementAt(index);
                            return CheckboxListTile(
                              controlAffinity: ListTileControlAffinity.trailing,
                              value: _expiringContractStatus["isCheck"], // ************
                              onChanged: (value) {
                                controller.itemChange(value, index); // ************
                                controller.update();
                              },
                              title: Text(
                                _expiringContractStatus["title"],
                                style: Get.textTheme.bodyText1,
                                overflow: TextOverflow.fade,
                                softWrap: false,
                                maxLines: 1,
                              ),
                            );
                          }),
                          initiallyExpanded: true,
                        );
                      }                   
                )
            ),
          ),
         // more widgets
        ],
      ),
    );
     }
     }
    

    This is SearchController.

    class SearchController extends GetxController {
    final expiringContractStatus = <Map>[
      {
        "title": "aaa",
        "isCheck": false
      },
      {
        "title": "bbb",
        "isCheck": false
      },
      {
        "title": "ccc",
        "isCheck": false
      }        
    ].obs;
    
    @override
    void onInit() async {
      await refreshSearch();
      super.onInit();
    }
    
    void itemChange (bool value, int index) {
      expiringContractStatus[index]["isCheck"] = value; // *************
      update();
    }
    }
    
  • Speeder
    Speeder about 2 years
    Thanks. Loren, Before I post this problem I have tried with wrapping the scrollview with Obx. but could not solve the problem. :(
  • Loren.A
    Loren.A about 2 years
    Ok, well with what you shared without an Obx or GetBuilder its definitely not gonna work, bug or no bug. See updated answer, GetBuilder should work.
  • Speeder
    Speeder about 2 years
    Great. this is working. thanks. You are the expert in flutter.
  • Loren.A
    Loren.A about 2 years
    No problem, happy to help.