Dave
Dave

Reputation: 5426

Flutter GetX why are controllers not auto-deleted when navigating away

Maybe I am misunderstanding something here, but I have followed the docs on https://pub.dev/packages/get to set up a controller for each of my pages.

e.g standard page stuff:

Pages:

PageIntro -> PageLogin -> PageHome etc.  

Controllers:

- IntroController
- LoginController
- HomeController

I've defined each of my pages the same way, e.g.:

class PageIntro extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final IntroController c = Get.put(IntroController(context));

    return Scaffold(
      body: _buildContent(), // you get the idea.
    );
  }
}

I was expecting that when navigating away from PageIntro to PageLogin, that the IntroController would be deleted, but it's not.

I know I can manually delete controllers with:

Get.delete<IntroController>();

But I shouldn't have to.

Unless I'm missing something/doing something really stupid, this seems more hassle, more messy that just having PageIntro extend StatefulWidget, then doing whatever I need to do in the dispose override method as usual.

Please can someone more knowledgable on this inform me?

Thanks.

Upvotes: 0

Views: 3261

Answers (2)

xaldarof
xaldarof

Reputation: 95

I think it will help you to avoid this error. You should call in inside of build method.

  @override
  Widget build(BuildContext context) {
    var controller = ControllerStateDispatcher<RecentScreenController>(
        RecentScreenController(),true) // if you want to save state, false if you want reset state)
        .get<RecentScreenController>();
  }


    abstract class Cleaner {
      void clear();
    }
    
    abstract class GetControllerProvider<T extends GetxController> {
      R get<R extends GetxController>();
    }
    
    class ControllerStateDispatcher<T extends GetxController> extends Cleaner
        implements GetControllerProvider {
    
      bool shouldSaveState;
    
      T controller;
    
      ControllerStateDispatcher(this.controller, [this.shouldSaveState = false]);
    
      @override
      void clear() {
        Get.delete<T>();
      }
    
      @override
      DispatcherController get<DispatcherController extends GetxController>() {
        if (!shouldSaveState) clear();
    
        controller = Get.put(controller);
        return controller as DispatcherController;
      }
    }

Upvotes: 1

Muhammad Talha
Muhammad Talha

Reputation: 187

In your case, binding is the way to go.

On the other hand, controllers are removed when the route is removed from the stack. In your case, you maybe pushing to the next screen rather than replacing it.

Upvotes: 1

Related Questions