Home > OS >  Update Flutter state with GetX when the routing changes
Update Flutter state with GetX when the routing changes

Time:01-21

I'm using GetX to manage the state of my Flutter app, and the structure of my pages consists of an ItemsListPage that lists some items, and an ItemDetailsPage that shows details about an specific item and lets the user change it or delete it. I'm managing state using GetX's Reactive state management, which means that, in order to update the state of my ItemsListPage, I need to update an observable variable itemsList that is inside the ItemsListController. This variable is updated on the onInit() method of the controller, which means that whenever the controller is instantiated the list should be updated with the data fetched from the API.

The controller of the ItemsListPage looks like this:

class ItemsListController extends GetxController {
  var itemsList = <AppEntity>[].obs;

  @override
  void onInit() {
    super.onInit();
    // Fetch items from the API and store them on itemsList:
    getApps();
  }
  //...
}

And the controller of the ItemDetailsPage is like this:

class ItemsDetailsController extends GetxController {
  void deleteItem() async {
    final response = await deleteItem();

    response.fold((failure) {
      // Deal with a failure on the request
    }, (response) {
      if (response.success) {
        // I want to update the state of the list from here   
        Get.toNamed('/main/');
        Get.snackbar('Deleted', 'Item deleted successfully!');
      }
    });
  }

The problem is that when the user changes or deletes an item (on the ItemDetails page), he gets redirected to the main page via Get.toNamed('/main'), and sees the old version of the list, because the onInit() method isn't called again.

Is there a way for me to trigger an action everytime the user is redirected to the ItemsList page? This would allow me to fetch the fresh data from the API and update the page. Another solution would be a way of updating the state of the ItemsListController from the ItemDetailsController, which would be even better, as it would not require another call to the back-end.

CodePudding user response:

If you are using get_cli, then you can pretty much generate and use named routes along with your view, controller and bindings. But if in case you are just using the state management without binding, then this problem may occur.

The thing happening in this scenario is, your controller is building one time and then your onInit method is called, after that you do some operation on your list like deleting or adding some data, and then when you go to another screen, your controller doesn't get disposed(Strange).

You can solve this by using these ways,

  1. Whenever you switch to another screen, let's say using Get.toNamed(route) or Get.offNamed(route) or Get.off(route), what you can do is before navigating to other screen, you can remove the controller form the memory like this,

Get.delete<ControllerName>();

In this way, your controller will be again reinstantiated when you open your screen again(Provided that you have put the Get.put(Controller()) In your widget.

  1. If you are using named routes then you can pretty much directly use them, you don't need to do anything in order to work with them. In case you're facing the error even if you have bindings and named routes then you can perform step 1.

  2. If you want to minimize the API calls then whenever the user deleted some item from the list, you can delete it locally and update the UI according to it. This way user won't have to see the loaders again and again.

  • Related