user2181948
user2181948

Reputation: 1938

Sharing data between two Flutter GetX Controllers

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();
    }
}

Upvotes: 0

Views: 219

Answers (2)

WebDesk Solution
WebDesk Solution

Reputation: 505

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
}

Upvotes: 0

Affan Minhas
Affan Minhas

Reputation: 567

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();
  }
}

Upvotes: 0

Related Questions