1

I have implemented a series of BLoCs for a flutter app and part of it works. The app is pretty simple and it tracks the state of a battle between two players with updates to the game state happening when the players press buttons. There is other state but this is the bit that isn't working and I can't figure out why.

I have created a cubit called BattleState and it extends Equatable. There is a state called InBattle that has a battleModel as the object with the current state of the two players in the game. When buttons are pressed on the UI the battleModel is updated and then a new InBattle state emitted with the new values.

  final BattleModel battleModel;

  const InBattle(
      {this.battleModel});

  @override
  List<Object> get props =>
      [battleModel];
}

The BattleModel is about what you expect, it contains a few state details and some functions to update them and it implements equatable as well

class BattleModel extends Equatable {

  BattleModel(){
    this.p1Name = '';
    this.p2Name = '';
...

@override
  List<Object> get props => [p1Name, p2Name, p1InitialPower, p2InitialPower, p1CurrentPower, p2CurrentPower];
}

The problem is that it doesn't work. I press the buttons to change the state and the UI doesn't update. I tracked through the debugger and the problem was that when it checked the state to see if it should update it thought the states were identical even though the power values had changed. Performing a hot reload also caused the display to update properly, so I know the state values are properly updating.

If I remove the equatable from the InBattle state then everything updates exactly as expected, but my understanding was that you wanted Equatable on the states because you don't want to trigger a build when the state is the same. In this application it doesn't really matter. The states are limited and the ways of state change are limited enough that the application does work if I drop Equatable but my understanding is that this is not the right way to implement it.

Am I using Equatable wrong and if so how? Or is the problem that I shouldn't just have the one InBattle state and I really should be emitting states that reflect what changed rather than just emitting InBattle's over and over until exit or the win condition happens?

user2939408
  • 153
  • 7

1 Answers1

1

Sorry if my answer misses your problem, but obviously the Equatable package should detect state changes if contents of the state change. But as a quick, temporary solution - maybe implement a 'transition' state - eg. "BattleStateUpdatingState" and emit it before new values are written to the "BattleStateUpdatedState"?

See this example of the method in the Cubit to fetch fresh info from the API as an inspiration:

Future<void> getUserInfo() async {
    emit(UserInfoLoading());
    try {
      final userInfo = await userInfoRepository.fetchUserInfo();
      if (userInfo != null) {
        emit(UserInfoLoaded(userInfo));
      }
    } on Exception {
      emit(UserInfoError('Problem loading userinfo'));
    }
  }