Search code examples
flutterobservableflutter-getx

Flutter GetX Obx not updating text on button press


Below I have a very simple GetX project that should basically load some data on button press asynchronously. However, I would like the button to change from 'PRESS ME' to 'LOADING' whilst the data is fetched. I cannot get my head around why the widget is not rebuilt when I change the observable status variable. Am I missing a fundamental concept here? The widget clearly does get re-drawn after the async method updateDetails finishes, but not when I change 'status' within the method...? Many thanks.

void main() async {
  runApp(TestApp());
}

class TestApp extends StatelessWidget {
  const TestApp({super.key});

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      theme: appTheme,
      home: TestWidget(),
    );
  }
}

class TestController extends GetxController {
  var status = 'PRESS ME'.obs;
    
  updateDetails() async {
    print('Loading');
    status('LOADING');
    sleep(1.seconds);
    print('Finished');
    status('PRESS ME');
  }
}

class TestWidget extends StatelessWidget {
  TestWidget({super.key});
  final TestController controller = Get.put(TestController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          onPressed: () {
            controller.updateDetails();
          },
          child: Obx(() {
            print('Redrawing text');
            return Text(controller.status.value);
          }),
        ),
      ),
    );
  }
}

Solution

  • sleep is not the way to wait in Flutter. Use awaiting a Future.delayed instead. So instead of

    sleep(1.seconds);
    

    do

    await Future.delayed(1.seconds);
    

    instead