Flutter GETX: How to remove Initialized Controller every time we navigate to other page/routes

Viewed 11486

newbie here. How do I re-run onInit() every time I push back to my screen? onInit() runs only once but navigating back to a previous screen does not delete the controller which was initialized (FetchData) hmmm..

I'm only using Get.back() every time I want to pop page, and Get.toNamed() every time I want to navigate on a named route

the only thing I want to happen is to delete the Initialized controller (FetchData) every time I pop the page but I have no Idea how to do it.

my GetxController

class FetchData extends GetxController {
    RxList items = [].obs;
    @override
    onInit() {
      fetchData();
      super.onInit();
    }
    
    Future<void> fetchData() async {
     var result = await http.get("api.url");
     items.value = result.body;
    }
}

Thanks in advance!

6 Answers

When I logout Get.off, Get.offUntil, Get.offAndToNamed methods doesnt remove my GetXController from memory.

then I tried below code and everything works fine.

 Get.offUntil(GetPageRoute(page: () => Login()), ModalRoute.withName('toNewLogin') );
   
     Timer(Duration(milliseconds: 300), ()=>Get.delete<MainPageController>());

You can use:

Get.delete<FetchData>();

You cannot put method fetchData() on super.onInit(). When you use Get.offAllName(), Get.offAndToName(), Get.offAll(), etc... Method fetchData() is still kept in memory => Cannot dispose or close it.

FIX:

class FetchData extends GetxController {
   RxList items = [].obs;
   @override
   onInit() {
     super.onInit(); // <--- swap code here
     fetchData(); // <--- swap code here
   }

   Future<void> fetchData() async {
      var result = await http.get("api.url");
      items.value = result.body;
   }
}

The onInit is only called once. You can use another method to run when back from another screen, for example, when call the new screen you can await until it closes and then call your method again:

//go to new screen
await Get.toNamed(screenName);
//after run my method
controller.fectchData();

if you want call the method only in some cases you can pass a bool back to ask if needs reload:

Get.back(result: true);

and in the screen that called:

//go to new screen
final result = await Get.toNamed(screenName);
    
if(result != null && result == true)//after run only if needed
controller.fectchData();

You can use

Get.offAndToNamed(url)

Use Get.offAllNamed. It will remove all controllers and create only the final destination route controller. Tested with get: ^4.3.8

        Get.offAllNamed("your final route");
Related