Search code examples
flutterblocflutter-getx

the equivalent of BlocListener in GetX


is there any equivelant to BlockListener in Getx, like to show a snackbar for example depending on state... like this example from Bloc pattern

body: BlocConsumer<PhotoBloc, PhotosState>(
        listener: (context, state) {
             if(state is PhotoErrorState) {
               return ScaffoldMessenger.of(context).showSnackBar(
                 SnackBar(content: Text(state.message))
               );
             }
        },

        builder: (context, state) {
          if (state is PhotoLoadingState) {
            return Center(child: CircularProgressIndicator(),);
          } else if (state is PhotoLoadedSuccessfullyState) {
            return Card(
              child: ListView.builder(
                itemCount: state.photos.length,
                itemBuilder: (context, i) {
                  return ListTile(
                    leading: CircleAvatar(child: Image.network(state.photos[i]
                        .url),),
                    title: Text(state.photos[i].title),

                    onTap: () {
                      context.read<NavigationCubit>().showPhotoDetails(state.photos[i]);
                    },
                  );

Solution

  • Workers are the Getx way of listening to any observable object. The ever function gets called any time an observable object changes.

    Lets say you really want to make it feel like bloc and you want to setup an observable enum so its similar to state.whateverState...

    You could do something like this by setting the listener in the onInit of the controller:

    enum Status { none, running, stopped, paused }
    
    class Controller extends GetxController {
     Rx<Status> status = Status.none.obs;
    
       @override
      void onInit() {
        super.onInit();
        ever(
          status,
          (value) {
            if (value == Status.running) {
              Get.snackbar('State Updated', 'Running');
            }
            if (value == Status.none) {
              Get.snackbar('State Updated', 'None');
            }
            if (value == Status.stopped) {
              Get.snackbar('State Updated', 'Stopped');
            }
            if (value == Status.paused) {
              Get.snackbar('State Updated', 'Paused');
            }
          },
        );
      }
    }
    

    Then from anywhere in the app you could do something like this:

     Get.find<Controller>().status.value = Status.paused;
    

    And that will show the paused snack bar.