Search code examples
fluttereventsstreamstatebloc

Flutter - Bloc only emits state when the state is not extending Equatable


I recently started using bloc and im stuck here.

I have a state:

class BasketState extends Equatable{
  final Map<Item, int> itemsOrdered;

  BasketState(this.itemsOrdered);

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

And the following bloc:

class BasketBloc extends Bloc<BasketEvent, BasketState> {
  Map<Item, int> _itemsOrdered = {};
  BasketBloc() : super(BasketState({}));

  @override
  Stream<BasketState> mapEventToState(BasketEvent event) async* {
    if (event is BasketAdd) {
      _itemsOrdered.putIfAbsent(event.item, () => event.amount);
    } else if (event is BasketRemove) {
      _itemsOrdered.remove(event.item);
    }
    yield BasketState(_itemsOrdered);
  }
}

Only the first time I send the BasketAdd event the bloc emits the state, then if I send the BasketAdd event again, the bloc emits nothing.

The only thing that worked is to remove the Equatable from the state, and I dont know why.

Am I doing something wrong?


Solution

  • Equatable is using that get props function to do the comparison.

    Change

      @override
      List<Object> get props => throw UnimplementedError();
    

    to

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

    and try again

    EDIT: The answer is in the comments now but another possible problem is mutability. In this case, rather than yielding itemsOrdered we should yield a new Map each time.

      yield BasketState(new Map<Item, int>.from(itemsOrdered));