skip to Main Content

I have a Flutter app using GetX with two controllers.

Both controllers have async onInit() methods. I want Controller1 to finish initialising first, before Controller2 initialising. This is not working – Controller2 is starting to

How do I wait for one controller to finish before the other one starts?

I have tried the following, which unfortunately calls Controller1‘s onInit() method twice, which I do not want. It should only call it once.

Widget:

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final uniqueId = '123';

    final Controller1 controller1 = Get.put(
      Controller1(),
      tag: uniqueId,
    );

    final Controller2 controller2 = Get.put(
      Controller2(),
      tag: uniqueId,
    );

    return Container(
      child: // Rest of widget code...
    );
}

Controller1:

class Controller1 extends GetxController {
    var dataToShare = ''.obs;

    @override
    Future onInit() async {
        /// async operation
        dataToShare.value = await ...

        super.onInit();
    }
}

Controller2:

class Controller2 extends GetxController {
    final String uniqueId;

    Controller2({
        required this.uniqueId,
    });

    @override
    Future onInit() async {
        // Wait for Controller1 to finish iniitalising first
        final Controller1 controller1 = await Get.find<Controller1>(
            tag: uniqueId,
        ).onInit();

        // Get data from Controller1
        String fetchedData = controller1.dataToShare.value;

        // Use the data from Controller1
        processData(fetchedData);

        super.onInit();
    }
}

2

Answers


  1. You achieve this by Get.putAsync. What you need to do is registering your controller by this way,

    class MyWidget extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final uniqueId = '123';
    
      
        Get.putAsync(() => Controller1(), tag: uniqueId);
        Get.putAsync(() => Controller2(uniqueId: uniqueId), tag: uniqueId);
    
        return Container(
          child: 
        );
      }
    }
    

    Then your controller 1 will go like this:

    class Controller1 extends GetxController {
      var dataToShare = ''.obs;
    
      @override
      Future<void> onInit() async {
        dataToShare.value = await ...
    
        super.onInit();
      }
    }
    

    Now controller 2 will wait for the operation of controller 1.

    class Controller2 extends GetxController {
      final String uniqueId;
    
      Controller2({
        required this.uniqueId,
      });
    
      @override
      Future<void> onInit() async {
        final Controller1 controller1 = Get.find<Controller1>(tag: uniqueId);
    
        String fetchedData = controller1.dataToShare.value;
    
        processData(fetchedData);
    
        super.onInit();
      }
    }
    
    Login or Signup to reply.
  2. Please try using the modification provided below; I believe it will be helpful.

    • Controller1 will be created using Get.create(), ensuring its initialization logic is called only once.

    Widget:

    final Controller1 controller1 = Get.create(() => Controller1(), tag: uniqueId);
    
    • The initialized flag tracks whether the initialization has occurred to avoid repeated calls.

    Controller1:

    var initialized = false.obs;
    
    if (!initialized.value) {
      initialized.value = true;
      // Initialization logic
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search