Home > OS >  My boolean bloc state variable stops changing after the first reassignment
My boolean bloc state variable stops changing after the first reassignment

Time:12-14

I am relatively new at flutter. I am creating a timer app using bloc. In the timer you are supposed to have a session, then a break and so on and so forth. To track which type of session to start(a break or session), I am using a boolean value isBreak which I am tracking in the SessionsBloc. Here is the definition of the SessionsState:

    part of 'sessions_bloc.dart';
    abstract class SessionsState extends Equatable { final bool isBreak; final int sessionCount; const SessionsState(this.isBreak, this.sessionCount);
    
    @override List<Object> get props => []; }
    
    class SessionsInitial extends SessionsState { const SessionsInitial(super.isBreak, super.sessionCount); }
    
    class SessionTrackingState extends SessionsState { const SessionTrackingState(super.isBreak, super.sessionCount); }

I then use A BlocListener to check for the TimerFinishedState from another bloc TimerBloc, after which I add an event, SessionTrackingEvent, that is supposed to change the aforementioned boolean value. Here is the code for the listener:

     listener: (context, state) {
            Task currentTask =
                BlocProvider.of<TasksBloc>(context).state.currentTask;
            bool isTimeBoxed = currentTask.isTimeBoxed;
            int sessionDuration;
            int breakDuration;
            if (state is TimerCompleteState) {
              //Get the SessionsBloc state
              final sessionState = BlocProvider.of<SessionsBloc>(context).state;
              //Get the current value of the isBreak boolean value
              bool isBreak = sessionState.isBreak;
              int sessionCount = sessionState.sessionCount;
              //Print statements: Can't Debug properly yet:(
              print(sessionState.isBreak);
              print(sessionState.sessionCount);
    
    
              if (isTimeBoxed) {
                sessionDuration = currentTask.sessionTimeBox!;
                breakDuration = currentTask.breakTimeBox ?? 2;
                // sessionCount = HiveDb().getTaskSessionCount(currentTask.taskName);
              } else {
                sessionDuration = 5;
                breakDuration = 3;
              }
    
              if (isBreak) {
                //Set timer with duration time
                BlocProvider.of<TimerBloc>(context)
                    .add(InitializeTimerEvent(duration: sessionDuration));
                //Add Event to track session count and next countdown if break or session
                BlocProvider.of<SessionsBloc>(context).add(SessionTrackingEvent(
                  isBreak: isBreak,
                  sessionCount: sessionCount,
                ));
              } else {
                //Add event to reset timer
                BlocProvider.of<TimerBloc>(context)
                    .add(InitializeTimerEvent(duration: breakDuration));
                //Emit a state that notifies Button Bloc that it's a break and deactivate repeat button.
                BlocProvider.of<TimerBloc>(context)
                    .add(OnBreakEvent(duration: breakDuration));
                //Add Event to track session count and next countdown if break or session
                BlocProvider.of<SessionsBloc>(context).add(SessionTrackingEvent(
                  isBreak: isBreak,
                  sessionCount: sessionCount  = 1,
                ));
              }
            }
          },

Finally, in the SessionsBloc, I only have super constructor which initializes the boolean value to false and one event handler that is supposed to change it as appropriate.

    class SessionsBloc extends Bloc<SessionsEvent, SessionsState> {
      SessionsBloc() : super(const SessionsInitial(false, 0)) {
        on<SessionTrackingEvent>((event, emit) {
          emit(SessionTrackingState(
              event.isBreak ? false : true, event.sessionCount));
        });
      }
    }

The expected result is that for each SessionTrackingEvent added, the boolean should be toggled to the opposite value. However, what actually happens is that it Works the first time, turning the initialized value of false to true and from there it just stays the same. Here is a screenshot of my print statement which outputs the value of IsBreak after every call to SessionTrackingEvent. Here is a screenshot of my print statement which outputs the value of IsBreak after every call to SessionTrackingEvent.

I have tried changing the variable type from final because I thought maybe it's a flutter constraint about reassigning variables. I have tried moving the reading of the block state value into the build method outside of the listener because I thought maybe it doesn't read the value as frequently.

What could be the problem, what might be preventing the value from changing as appropriate?

CodePudding user response:

You forgot to pass your SessionsState properties into props list, so the Bloc can't differentiate between old and new states without it.

abstract class SessionsState extends Equatable {
  final bool isBreak;
  final int sessionCount;
  const SessionsState(this.isBreak, this.sessionCount);

  @override
  List<Object> get props => [isBreak, sessionCount]; // your props should go here like this
}
  • Related