Hamou Ouyaba
Hamou Ouyaba

Reputation: 1489

Get : the improper use of a GetX has been detected

Since I'm new to using Getx and while I'm trying to create a drawer using Getx I'm facing this error. What did I do wrong? All I want is to get rid of this error.

Edit: the two methods invisibleSubMenu() and iconMenu() are showing the same error.

The following message was thrown building Obx(has builder, dirty, state: _ObxState#b6fe5):
      [Get] the improper use of a GetX has been detected.
      You should only use GetX or Obx for the specific widget that will be updated.
      If you are seeing this error, you probably did not insert any observable variables into
GetX/Obx
      or insert them outside the scope that GetX considers suitable for an update
      (example: GetX => HeavyWidget => variableObservable).
      If you need to update a parent widget and a child widget, wrap each one in an Obx/GetX.

The relevant error-causing widget was:
  Obx

Here's the code.

Drawer class :

class DrawerScreen extends StatelessWidget {
  final bodyCtrl = Get.find<BodyController>();
  DrawerScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      child: row(),
    );
  }

  row() {
    return Row(
      children: [
        iconMenu(),
        invisibleSubMenu(),
      ],
    );
  }

  iconMenu() {
    return Container(
      color: Colors.grey[400],
      width: 100,
      child: ListView.builder(
          itemCount: drawerItemscdm.length,
          itemBuilder: (context, index) {
            return Obx(
              () => InkWell(
                onTap: () {
                  bodyCtrl.selectMenuIndex(index);
                },
                child: Container(
                  height: 45,
                  alignment: Alignment.center,
                  child: Icon(
                    drawerItemscdm[index].icon,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          }),
    );
  }

  invisibleSubMenu() {
    return Container(
      width: 150,
      color: Colors.red,
      child: Obx(
        () => ListView.builder(
            itemCount: drawerItemscdm.length,
            itemBuilder: (context, index) {
              Menucdm menu = drawerItemscdm[index];
              bodyCtrl.selected.value = bodyCtrl.selectedIndex.value == index;
              if (bodyCtrl.selected.value) {
                return subMenuWidget(menu.title, menu.submenu);
              }
              return invisibleWidget();
            }),
      ),
    );
  }

  Container subMenuWidget(String title, List<Map> submenus) {
    return Container(
      color: Colors.blueGrey,
      height: 200,
      child: ListView.builder(
          itemCount: submenus.length,
          itemBuilder: (context, index) {
            return Column(
              children: [
                ...submenus.map((element) => ListTile(
                      leading: Icon(element['icon']),
                      title: Text(element['title']),
                    )),
              ],
            );
          }),
    );
  }

  invisibleWidget() {
    return Container(
      height: 45,
      color: Colors.green,
    );
  }
}

The MenuCdm class :

class Menucdm {
  final IconData icon;
  final String title;
  final List<Map> submenu;

  Menucdm(this.icon, this.title, this.submenu);
}

The drawerItemscdm list:

List<Menucdm> drawerItemscdm = [
  Menucdm(FontAwesomeIcons.book, 'A', []),
  Menucdm(FontAwesomeIcons.book, 'B', [
    {
      'icon': FontAwesomeIcons.shop,
      'title': 'BA',
    },
    {
      'icon': FontAwesomeIcons.shop,
      'title': 'BB',
    },
    {
      'icon': FontAwesomeIcons.shop,
      'title': 'BC',
    },
    {
      'icon': FontAwesomeIcons.shop,
      'title': 'BD',
    }
  ]),
  Menucdm(FontAwesomeIcons.book, 'C', [
    {
      'icon': FontAwesomeIcons.gear,
      'title': 'CA',
    },
    {
      'icon': FontAwesomeIcons.gear,
      'title': 'CB',
    },
    {
      'icon': FontAwesomeIcons.gear,
      'title': 'CC',
    }
  ])]

The controller class :

class BodyController extends GetxController {
  final selectedIndex = (-1).obs;
  final selected = false.obs;

  void selectMenuIndex(int index) {
    selectedIndex.value = index;
  }
}

Upvotes: 0

Views: 627

Answers (2)

Soul
Soul

Reputation: 1

I have a conditional obx dependency like:

Widget buildView() {
  return (Obx(() => Column(children: [
    if (controller.argumentData.dict.isEmpty)
      Text(controller.state.value),
  ])));
}

Also face this error

My workaround is

Widget buildView() {
  return (Obx(() {
    0.obs.value;  // add line
    return Column(children: [
      if (controller.argumentData.dict.isEmpty)
        Text(controller.state.value),
    ]);
  }));
}

Upvotes: 0

Amit Bahadur
Amit Bahadur

Reputation: 269

You are using Obx where there is nothing to change with getx i.e There must be .value written at the suffix of the variable data you are changing because obx will only look for .value

Drawer class : in this class you are using obx but there is no value and you are just calling the getx controller function and passing index into that but not changing the value that's why it gives error

  iconMenu() {
    return Container(
      color: Colors.grey[400],
      width: 100,
      child: ListView.builder(
          itemCount: drawerItemscdm.length,
          itemBuilder: (context, index) {
            return Obx(
              () => InkWell(
                onTap: () {
                  return bodyCtrl.selectMenuIndex(index);
                },
                child: Container(
                  height: 45,
                  **alignment: Alignment.center,
                  child: Icon(
                    drawerItemscdm[index].icon,
                    color: Colors.white,
                  ),
                ),
              ),
            );
          }),
    );
  }

Upvotes: 2

Related Questions