Barzan Saeedpour
Barzan Saeedpour

Reputation: 105

How to clear data from a bloc when dispose the page?

I am using flutter_bloc on the second page of my flutter app, how can I clear bloc's data when I dispose of this page (like Navigate back to my first page)?

Upvotes: 3

Views: 6592

Answers (3)

Hossein Yousefpour
Hossein Yousefpour

Reputation: 4953

If you need to keep the emits and initialState implementations in the cubits, you can declare:

abstract class CubitWithClearState<State> extends Cubit<State> {
  CubitWithClearState(super.initialState);

  clearState();
}

And change all the app cubits to extend CubitWithClearState instead of the Cubit.

Example:

class SomeCubit extends CubitWithClearState<SomeState> {
SomeCubit() : super(SomeStateInitial())

  @override
  clearState() {
    emit(SomeStateInitial());
  }
}

And then:

context.read<SomeCubit>().clearState();

Upvotes: 0

Joel Garc&#237;a
Joel Garc&#237;a

Reputation: 36

If someone else is trying to clean the bloc data (for example, after a logout) the extensions could be a good approach. For example, if you have a bloc like the next one:

class TableUIBloc extends Bloc<TableUIEvent, TableUIState> {
  TableUIBloc() : super(TableUIInitial()) {
    on<TableUIEvent>((event, emit) {
      switch (event.runtimeType) {
        case UpdateShowedColumns:
          // The columns the user is trying to show
          final showedColumns = (event as UpdateShowedColumns).showedColumns;

          // updating the showed columns
          emit(
            TableUIUpdated(
              showedColumns: showedColumns
            ),
          );
          break;
      }
    });
  }
}

@immutable
abstract class TableUIEvent {}

/// Updates the list of showed columns on the table
class UpdateShowedColumns extends TableUIEvent {
  final List<TableColumn> showedColumns;

  UpdateShowedColumns({
    required this.showedColumns,
  });
}

@immutable
abstract class TableUIState {
  final List<TableColumn> showedColumns;

  const TableUIState({
    required this.showedColumns,
  });
}

class TableUIInitial extends TableUIState {
  TableUIInitial()
      : super(
          showedColumns: [
            TableColumn.stone,
            TableColumn.rating,
            TableColumn.team,
          ]
        );
}

You can create an extension an add the functionality of 'clean' the bloc data, emiting the initial state of the bloc:

/// An extension to reset a bloc to its default state.
extension BlocReset on Bloc {
    void reset(dynamic initialState) {
        // ignore: invalid_use_of_visible_for_testing_member
        emit(initialState);
    }
}

So when you want to clean up the state of a determined bloc you only have to import the extension and call the 'reset' method somewhere on your code, and provide the initial state datatype:

import 'package:your_project/path/to/extension.bloc.dart';

(context.read<TableUIBloc>()).reset<TableUIInitial>();

This is useful when you have a lot of blocs and you want to clean them all without having to create a new event to restore the state to the initial value for every single one. Here is an example of how I cleaned up the data of all the blocs on the system I'm developing.

// Cleaning all the blocs
(context.read<ClientBloc>()).reset(ClientInitial());
(context.read<TeamBloc>()).reset(TeamInitial());
(context.read<StoneBloc>()).reset(StoneInitial());
(context.read<AuthBloc>()).reset(AuthInitial());
(context.read<CalendarBloc>()).reset(const CalendarInitial());
(context.read<ColorBloc>()).reset(ColorInitial());
(context.read<OAuthBloc>()).reset(OAuthInitial());
(context.read<TableUIBloc>()).reset(TableUIInitial());
(context.read<OpportunityBloc>()).reset(OpportunityInitial());
(context.read<UserBloc>()).reset(UserInitial());

Upvotes: 1

Federick Jonathan
Federick Jonathan

Reputation: 2864

Bloc is using stream, unless you emit new event the state won't change. If you want "clear" the Bloc after navigating to different route, you can emit an event that yield an initialState of the Bloc in @override initS

Upvotes: 3

Related Questions