skip to Main Content

I have created a BLoC (8.0.0) in Flutter that handles events in the UI. I have a ToggleButtons widget where the user toggles between three buttons and whichever one is currently selected, returns a list of entities from the database which are then displayed on the screen. These are entities that have, among other parameters, the bool isSale and bool isClosed, and pressing each of the buttons should tell BLoC to search the database for entities with a different combination of these booleans, namely:

1 - isSale = true, isClosed = false
2 - isSale = true, isClosed = true 
3 - isSale = false, isClosed = false

I think the error must be somewhere in the code I’m going to post.

I have created states as follows:

abstract class DocViewerState extends Equatable {
  const DocViewerState();
}

class DocViewerLoadingState extends DocViewerState {
  @override
  List<Object> get props => [];
}

class DocViewerLoadedState extends DocViewerState {
  bool isSale;
  bool isClosed;
  int? selectedIndex;

  DocViewerLoadedState({required this.isSale, required this.isClosed, required this.selectedIndex});
  @override
  List<Object> get props => [isSale, isClosed];
}

The event I use to trigger this function looks like this:

abstract class DocViewerEvent extends Equatable {
  const DocViewerEvent();
}

class ModeChangedEvent extends DocViewerEvent {
  bool isSale;
  bool isClosed;

  ModeChangedEvent({required this.isSale, required this.isClosed});
  @override
  List<Object?> get props => [isSale, isClosed];
}

I have set up an event handler to change the search mode, the function of which looks like this:

  void _onModeChanged(ModeChangedEvent event, Emitter<DocViewerState> emit) {
    emit(DocViewerLoadingState());
    this.isSale = event.isSale;
    this.isClosed = event.isClosed; // This is here because of the search stream outside of this function
    try {
      emit(DocViewerLoadedState(
        isClosed: event.isClosed,
        isSale: event.isSale,
        selectedIndex: null,
      )); // This emit works only for the first and third combination
    } catch (e) {
      print(e); /// I tried to put this here because I thought maybe there is some silent exception. 
                /// There is none.
    }
    print(event.isSale); // These are for printing the results, they are described below.
    print(event.isClosed);
    print(state);
  }

I double checked that I’m using Equatable for the states and event. I also tried setting up the try catch code that is above. These are results of prints below emitting:

1st combination (

I/flutter ( 5019): true
I/flutter ( 5019): false
I/flutter ( 5019): DocViewerLoadedState(true, false)

2nd combination

I/flutter ( 5019): true
I/flutter ( 5019): true
I/flutter ( 5019): DocViewerLoadingState()

3rd combination

I/flutter ( 5019): false
I/flutter ( 5019): false
I/flutter ( 5019): DocViewerLoadedState(false, false)

As you can see, the new state isn’t updating although the parameters are passed correctly. What can I do to make it work as it should?

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution. For some reason, parameter isClosed seems to be some kind of keyword. Renaming isClosed to closed in all instances where it's used above suddenly made the emiting work.


  2. This is just a very wild guess, but it might be a race condition. Can you make the method async and add a delay before printing out the state?

    Also, what I usually do is to use a Bloc Observer to monitor state changes:

    class _DebugBlocObserver extends BlocObserver {
      @override
      void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
        super.onChange(bloc, change);
        log('onChange(${bloc.runtimeType}, $change)');
      }
    
      @override
      void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
        log('onError(${bloc.runtimeType}, $error, $stackTrace)');
        super.onError(bloc, error, stackTrace);
      }
    }
    

    You can then register this observer when starting your app:

    Bloc.observer = _DebugBlocObserver();

    This prints out all state changes.

    Here is the documentation: https://bloclibrary.dev/#/fluttercountertutorial?id=blocobserver

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search