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?
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.