Search code examples
flutterbloc

When to use Equatable and EquatableMixin


I have a Bloc in Flutter whose state looks like this:

class MyState extends Equatable {
  
  const MyState(this.items);
  
  // a list of objects which in themselves are nested
  final Iterable<MyCustomType> items;
  
    @override
  List<Object?> get props => [items];
}

My Emit:

// returns true just for demonstration.
// I now realize that this returns a new iterable, hence the equality failure.
items = items.where((x) => true)

// copyWith is omitted, but functions properly as you might expect
emit(state.copyWith(items: items));

The problem is, my .where() returns a new iterable, but the items are the same and therefore a new build is called.

Any ideas? Does it have anything to do with EquatableMixin?


Solution

  • The main issue is with your where method. This method in Dart returns a new iterable rather than modifying the existing one in-place. When you emit the state with the new iterable, Equatable sees it as a different object, and thus a new state is emitted even if the content is the same.

    You can fix it by create a new List with the filtered items and pass that to your emit function.

    final updatedItems = state.items.where((x) => true).toList(); // Convert to a list
    
    // Copy the state and update the items with the filtered list
    final newState = state.copyWith(items: updatedItems);
    
    // Emit the new state
    emit(newState);
    

    By converting the filtered iterable to a list using .toList(), you create a new list with the same content, and when you pass it to emit, Equatable will see it as the same content and not trigger a new state emission if the content is the same.

    Hope this helps.