2

I'm using Obs/Obx in 2 routes, one works fine but one doesn't. There are 2 obs vars in the controller.

import 'package:get/get.dart';

class CountController extends GetxController {
  final vcount = 0.obs; 
  final ncount = 0.obs; 

  static CountController get to => Get.find<CountController>();

  @override
  void onInit() {
    super.onInit();
  }

  setVcount(int vehnum) {
    vcount(vehnum);
  }

  setNcount(int notenum) {
    ncount(notenum);
  }
}

The one I use on a ListTile in the app drawer (vcount) works as expected. The other one is on an appbar action, the only action on this appbar. I want to disable the TextButton if ncount is 0.

   appBar: AppBar(
      actions: <Widget> [
        Obx(() =>
          TextButton(
            child: _appBarChild(),
            onPressed: () => nCountController.ncount.value == 0 ? null : _switchView(),
            // onPressed: () => _switchView(),

          ),
        ),

      ], 
  )

The ncount value is set from a child of the route.

nCountController.setNcount(_queryResult.length);

Everything is the same, import controller.dart, "final (nC)countController = CountController.to;", setting the obs vars etc, the only difference is the type of widget, but when I run it I get the error:

======== Exception caught by widgets library ======================================================= The following message was thrown building Obx(has builder, dirty, state: _ObxState#11cd1): [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.

Am I missing something or doesn't Obx work in an appbar?

Babsky
  • 23
  • 1
  • 6

1 Answers1

1

You are actually doing nothing with the view by using onPressed: () => nCountController.ncount.value == 0 ? null : _switchView()

You should use onPressed: nCountController.ncount.value == 0 ? null : ()=> _switchView()

Explanation: ()=> null & null aren't same. You have to pass onPressed: null in order to disable the button and not onPressed: ()=> null

S. M. JAHANGIR
  • 4,324
  • 1
  • 10
  • 30
  • Couldn't see the wood for the trees! Thank you, I knew it had to be something simple. That's solved that problem but now have a "setState() or markNeedsBuild() called during build." error – Babsky Oct 29 '21 at 21:10
  • Have you tried `Obx(()=>nCountController.ncount.value == 0 ? TextButton(..., onPressed: null): TextButton(..., onPressed: ()=> _switchView())` If that still gives the same error, then maybe it has something to do with the `_switchView()` method. – S. M. JAHANGIR Oct 29 '21 at 21:19
  • Can't get it to like that but the problem is that the route is refreshed by the grandchild by passing a function. I tried wrapping the TextButton in a Visibility widget as it's ok to hide it if there's nothing in the list, but it's the same story. If I use Obx it complains about "setState or markNeedsBuild during build" but if I don't it obviously doesn't refresh as the list changes. What is the proper way to do it? I tried passing a value alongside the function that passed, but I couldn't get that working. – Babsky Oct 29 '21 at 22:15
  • Why you should use Visibility if you want to hide the TextButton in this case? You can use a blank Container. – S. M. JAHANGIR Oct 30 '21 at 02:44
  • what's wrong with using visibilty? – Babsky Oct 30 '21 at 12:31